【问题标题】:Validation of Smart Health Card token fails智能健康卡令牌验证失败
【发布时间】:2021-09-22 03:54:44
【问题描述】:

我正在编写下面的代码来获取我想要验证的 jwt 令牌 SMART Health Cards Validation SDK

var jose = require("node-jose");
const {JWS} = require("node-jose");


async function a1(){
    try {
    
const keystore={
    keys: [
        {
            kty: 'EC',
            d: 'gLkNmSBFWR67hEu62eVfVWhFbLGl309jOszsocqbexE',
            use: 'sig',
            crv: 'P-256',
            kid: '6d858102402dbbeb0f9bb711e3d13a1229684792db4940db0d0e71c08ca602e1',
            x: '5R2yrryD1ztBYnyKyQF5r5kzPUjnVnmR5pMe7H9ykNU',
            y: 'VaqqjG0N2rSuijP9P9QiOjX4XEhIl8k8fzA6FZTSMhY',
            alg: 'ES256'
        }
    ]
}

const ks = await jose.JWK.asKeyStore(keystore);
const rawKey = ks.get(keystore.keys[0].kid)
const key =  await jose.JWK.asKey(rawKey);

const payload =JSON.stringify({ "iss" : "https://spec.smarthealth.cards/examples/issuer", "sub": "1234567890", "name": "John Doe", "iat": 1516239022});

    const token =await jose.JWS.createSign( {format: 'compact'},key).update(payload, "utf8").final();

    console.log(token);
    }catch (err) {
    console.log(err);
  }
    
}
a1();

我正在获取令牌:

eyJhbGciOiJFUzI1NiIsImtpZCI6IjZkODU4MTAyNDAyZGJiZWIwZjliYjcxMWUzZDEzYTEyMjk2ODQ3OTJkYjQ5NDBkYjBkMGU3MWMwOGNhNjAyZTEifQ.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkVyaWMgRC4iLCJyb2xlIjoiYWRtaW4iLCJpYXQiOjE1MTYyMzkwMjJ9.dbjb9YHFCWaFYGQYyGDDL1iFvqk1Ed9k3-PAhVx4NtvFml1q0VcpW854IXW_J47f6Vf1otm2WeftVQHjY3K4vg P>

当我使用这个命令时:

node . --path C:\Users\User\Documents\Saguaro\health-cards-validation-SDK-main\jws.text --type jws

在 sdk 文件中,出现以下错误:

错误
│ · JWS 标头缺少 'zip' 属性。
│ · 膨胀 JWS 有效负载时出错。您是否使用原始 DEFLATE 压缩?
│ 不正确的标题检查
│ · JWS 验证失败:在颁发者集中找不到 'kid' = 6d858102402dbbeb0f9bb711e3d13a1229684792db4940db0d0e71c08ca602e1 的密钥

请告诉我发行者集是什么以及如何将孩子价值放入发行者集中。 另外,放气压缩是什么意思以及如何解决这个问题。 请注意:以上为伪代码。

【问题讨论】:

    标签: node.js jwt hl7-fhir jwk smart-on-fhir


    【解决方案1】:

    你基本上有两个主要错误:

    第一个(我将这两条消息视为一个错误的一部分)

    · JWS 标头缺少“zip”属性。
    · 膨胀 JWS 有效负载时出错。您是否使用原始 DEFLATE 压缩?

    表示您的令牌格式不正确。

    Smart Health Cards require a compressed payload,使用 DEFLATE(请参阅 RFC1951)算法,以及带有值“DEF”的“zip”标头,以显示有效负载已压缩,我只看到在 @ 987654323@,但不适用于 JWS。大多数 JWT 库可能不为签名令牌提供压缩负载,并且 node-jose 也仅支持 JWE,因此必须手动完成。

    为此,您可以使用 zlib 压缩有效负载并手动将"zip":"DEF" 添加到标头:

    const zlib = require("zlib");
    ...
    const payload = "{...}"  // very long payload, see example in https://mikkel.ca/blog/digging-into-quebecs-proof-of-vaccination/
    const payloadBuf = zlib.deflateRawSync(payload)
    const token =await jose.JWS.createSign({alg: 'ES256', fields: { zip: 'DEF' }, format: 'compact'}, key).update(payloadBuf, "utf8").final();
    

    第二个错误是:

    JWS 验证失败:在颁发者集中找不到 'kid' = 6d858102402dbbeb0f9bb711e3d13a1229684792db4940db0d0e71c08ca602e1 的密钥

    这意味着要验证您的令牌,需要由给定 keyId (kid) 标识的公钥,并且该密钥应在您的“颁发者集”中提供。

    根据linked documentation验证器工具有一个参数

     -k, --jwkset <key>         path to trusted issuer key set
    

    进一步描述为:一个 JSON Web 密钥 (JWK) 集,对颁发者公共签名密钥进行编码

    所以基本上你必须将你的密钥库作为 JWKS (JSON Web Key Set) 存储在一个文件中(例如 issuerPublicKeys.json) 如下所示,并在参数中提供该文件的路径。在验证您的令牌期间,验证器将从令牌头中读取kid,并尝试在提供的密钥集中找到相应的密钥。

    {
      "keys":
        [
          {
            "kty": "EC",
            "kid": "6d858102402dbbeb0f9bb711e3d13a1229684792db4940db0d0e71c08ca602e1",
            "use": "sig",
            "alg": "ES256",
            "crv": "P-256",
            "x"  : "SVqB4JcUD6lsfvqMr-OKUNUphdNn64Eay60978ZlL74",
            "y"  : "lf0u0pMj4lGAzZix5u4Cm5CMQIgMNpkwy163wtKYVKI"
          }
        ]
    }
    

    注意:d 值(私钥)不包括在内,您只应显示公钥。

    我下载了package,在payload中添加了一些更多需要的数据(示例找到here),测试它首先得到了上面提到的错误,在提供参数--jwkset issuerPublicKeys.json后消失了:

    node . --path jws.txt --type jws --jwkset issuerPublicKeys.json
    

    也就是说,jwt 可以用公钥来验证!

    Keyset 本身也可以验证:

    node . --type jwkset --path issuerPublicKeys.json
    

    使用当前值,结果将是:

    验证键集

    └─ 错误
    ·
    key[6d858102402dbbeb0f9bb711e3d13a1229684792db4940db0d0e71c08ca602e1]: >'kid' 与颁发者密钥中的指纹不匹配。预期:a7qE0Y0DyqeOFFREIQSLKfu5WlbckdxVXKFasfcI-Dg,实际:
    6d858102402dbbeb0f9bb711e3d13a1229684792db4940db0d0e71c08ca602e1
    验证完成

    提到的指纹与孩子相同。所以当你用值“a7qE0Y0DyqeOFFREIQSLKfu5WlbckdxVXKFasfcI-Dg”替换孩子时,错误就消失了:

    验证键集
    验证完成

    【讨论】:

      猜你喜欢
      • 2012-09-16
      • 2019-05-05
      • 1970-01-01
      • 2022-10-19
      • 2020-12-18
      • 2018-07-23
      • 2014-01-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多