使用 jose4j 验证具有分离负载的 JWS 失败

Posted

技术标签:

【中文标题】使用 jose4j 验证具有分离负载的 JWS 失败【英文标题】:Verifying JWS with detached payload using jose4j fails 【发布时间】:2022-01-19 15:25:32 【问题描述】:

我在验证带有分离负载的 JWS 时遇到问题。我基本上复制了 jose4j 文档中 example provided 中的所有步骤,但由于某种原因,验证仍然返回 false,而它应该成功。

这是我正在使用的代码,使用的是最新版本的 jose4j。

// signature is the complete JWS in the form: "JOSE Header".."JWS Signature"
// payload is the unencoded JSON string that makes up the request body
public boolean verifySignature(String signature, String payload) 

        JsonWebSignature jws = new JsonWebSignature();
        jws.setKnownCriticalHeaders(critHeaders); //critical headers from documentation
        //Algorithm as provided in documentation
        jws.setAlgorithmConstraints(new AlgorithmConstraints(AlgorithmConstraints.ConstraintType.PERMIT, 
                                                            AlgorithmIdentifiers.ECDSA_USING_P256_CURVE_AND_SHA256));
        jws.setPayload(payload);
        try 
            jws.setCompactSerialization(signature);
            String keyId = jws.getKeyIdHeaderValue();
            String keyType = jws.getKeyType();
            String keyAlg = jws.getAlgorithmHeaderValue();
            //Retrieve key from cached jwks
            JsonWebKey usedKey = jwks.findJsonWebKey(keyId, keyType, "sig", keyAlg);
            jws.setKey(usedKey.getKey());
            return jws.verifySignature();
         catch  (JoseException e) 
            //log
            return false;
               
    

【问题讨论】:

由于某种原因验证仍然返回 false - 您至少应该记录异常并告诉我们结果。您能否添加指向您所引用示例的链接?这也会很有帮助。 @jps 也不例外,jws.verifySignature(); 正在返回布尔值 false,而它应该是 true。我已将链接添加到有问题的示例 【参考方案1】:

尝试将jws.setPayload(payload); 向下移动到jws.setCompactSerialization(...); 行之后。 我认为 jws.setCompactSerialization(...); 将有效负载覆盖为空字符串,这会破坏签名验证。

【讨论】:

不幸的是,这不是解决方案 作为参考,您的预感是正确的,因为在紧凑序列化将 payloadBytes 重置为空数组之前设置了有效负载 我无法让它工作,不得不切换到 Nimbus JOSE,所以如果你愿意,我可以在 bitbucket 上打开一个问题,以便你进行调查? 当然,如果你能提供足够的信息来调查它。就像使用的代码的 sn-p、JWS、有效负载、公钥/JWK 等。以及有效的 Nimbus 代码的 sn-p。 完成,祝调试顺利!【参考方案2】:

Brian Campbell 在 jose4j Bitbucket 上对此进行了研究,这是他的解决方案

添加一个 jws.setEncodedPayload(null);在 jws.setCompactSerialization(signature) 之后;会成功的。

显然在我的用例中编码/未编码的有效载荷之间存在一些不一致

【讨论】:

以上是关于使用 jose4j 验证具有分离负载的 JWS 失败的主要内容,如果未能解决你的问题,请参考以下文章

如何在空手道中创建jws消息签名[重复]

嵌套 JWS + JWE 与具有身份验证加密的 JWE

使用由 jose4j 生成的令牌在 node.js 中使用 jsonwebtoken 验证 JWT 失败

jose4j JwtConsumer 的验证密钥

可靠地验证 JWS 证书链和域

使用 PHP 验证来自 Android SafetyNet 的 JWS 响应