当前位置: 首页 > 知识库问答 >
问题:

JSON Web签名(Ninbus JOSE JWT)

严修诚
2023-03-14

我想用JSON Web签名(JWS)做一个项目,并且我想发送用于签名的证书的公钥,以便在收到该公钥后可以验证消息。我正在使用Ninbus JOS JWT库。我可以对JSON对象进行签名,并且可以看到公钥,但是我无法正确验证它。代码如下:

// Create RSA-signer with the private key
JWSSigner signer = new RSASSASigner(_signatureKey_);                                                    // PrivateKey

com.nimbusds.jose.util.Base64 b64 = new com.nimbusds.jose.util.Base64(_x509certificate.toString());     // X509Certificate
ArrayList<com.nimbusds.jose.util.Base64> certificados = new ArrayList<com.nimbusds.jose.util.Base64>();
certificados.add(b64);

RSAPublicKey _rsaPublicKey = (RSAPublicKey)_x509certificate.getPublicKey();  // Get the public key of the X509Certificate
RSAKey jwk = new com.nimbusds.jose.jwk.RSAKey.Builder( new Base64URL( _rsaPublicKey.getModulus().toString()),  new Base64URL( _rsaPublicKey.getPublicExponent().toString()))
    .x509CertChain(certificados)
    .build();

JWSHeader _jwsHeader = new JWSHeader.Builder(JWSAlgorithm.RS256).
    x509CertChain(certificados).
    jwk(jwk).
    build();

// Prepare JWS object with simple string as payload
JWSObject jwsObject = new JWSObject(_jwsHeader, new Payload(_jsonObject));

// Compute the RSA signature
jwsObject.sign(signer);

// Validation OK : This validation works
JWSVerifier verifier = new RSASSAVerifier(_rsaPublicKey);
boolean signatureValid = jwsObject.verify(verifier);        // ---> True, OK


// Now I want to validate the JWSObject getting the public key from the same JWSObject. This validation Fails
JWK _jwk = jwsObject.getHeader().getJWK();
RSAKey _rsakey = (RSAKey)_jwk; 
RSAPublicKey _rsaPublicKey2 = _rsakey.toRSAPublicKey();

JWSVerifier verifier2 = new RSASSAVerifier(_rsakey.toRSAPublicKey());
boolean verificado2 = jwsObject.verify(verifier2);      // False!

// Another option, this fails too
RSAKey __rsaKey2 = new com.nimbusds.jose.jwk.RSAKey.Builder( _rsakey.toRSAPublicKey() ).x509CertChain(_jwk.getX509CertChain()).build();
JWSVerifier verifier3 = new RSASSAVerifier(__rsaKey2);
boolean verificado3 = jwsObject.verify(verifier3);      // False!

公钥是:“Sun RSA公钥,2048位”,但当我从JWK(_RSA公钥2)获得它时,我得到了“Sun RSA公钥,3696位”,我不知道为什么。

谢谢

共有1个答案

华景明
2023-03-14

在接收方,在信任密钥之前,是否验证X.509证书颁发者、主题和链?在接收方确定可以信任JWS中包含的证书之前,不得尝试签名验证。

另一个注意事项:不要在JWS标头中包含公共JWK。这应该仅用于ECDH中的短暂公钥(用于JWE的不同alg)。在JWS标头中传递证书链就足够了,但是在使用其公钥之前,您必须验证它/找出证书是否可信。

库不会验证/找出证书是否可以为您信任!

如果第二次签名验证失败,那么用于对JWS进行签名的密钥可能与X.509证书附带的密钥不一样(根据报告的不同长度——2048位与3696位)。

 类似资料:
  • Pushes 签名 git push can be instructed to sign the push. The server may use this to control the execution of certain hooks: git push 可以被指示进行签名 push。服务器可以使用它来控制一些钩子的执行: ❯ git push --signed Github 现在貌似并没有

  • Merges 签名 git merge 命令可以在合并没有使用 --verify-signatures 命令带有不可信 GPG 签名的 commit/branch 时检查和拒绝 如果被合并的分支中有任何没有被有效签名认证的提交,合并将不会继续。 Merge commit 本身也是可以被签名的(使用 -S): ❯ git checkout -b enhancement/foo ❯ touch qux

  • Commits 签名 在上文提到的 git 仓库中添加一个新文件,并使用 -S 标签来提交(commit)它。(注意不是 -s 标签,在 commit 命令下它意味着 Signed-Off): ❯ touch biz ❯ git add biz ❯ git commit -S -m "Add biz" 你可以通过在 ~/.gitconfig.local 文件中添加下列内容来开启 commit 自动

  • Tags 签名 假设你有一个额外的文件可以在主 ~/.gitconfig 中添加 gitconfig 设置: [include] path = .gitconfig.local 配置 ~/.gitconfig.local 文件让其指向你插入的 GPG 签名钥匙: [user] signingkey = <signingKeyId> 开启 git tag -m <message> 来

  • 签名 ConsenSys的Infura服务提供了在云端运行的以太坊客户端的能力,所以你不必自己运行一个独立的以太坊客户端以便与以太坊一起工作。 当你注册这个服务时,你可以提供一个token令牌,你可以使用它连接到相关的以太坊网络: 以太网网络/公有链: https://mainnet.infura.io/<your-token> 以太坊测试网络/测试链(Rinkeby): https://rink

  • 签名算法是使用私钥签名,公钥验证的方法,对一个消息的真伪进行确认。如果一个人持有私钥,他就可以使用私钥对任意的消息进行签名,即通过私钥sk对消息message进行签名,得到signature: signature = sign(message, sk); 签名的目的是为了证明,该消息确实是由持有私钥sk的人发出的,任何其他人都可以对签名进行验证。验证方法是,由私钥持有人公开对应的公钥pk,其他人

  • 前言 随着区块链等相关技术的创新和突破,很多有形或无形资产都将实现去中心化,数字资产将无处不在。比如我们这里分享的 亿书 就是要把数字出版物版权进行保护,实现去中心化,解决业界多年来版权保护不力的难题。 无论数字资产,还是数字出版版权,都是有明确所有权的,当前实现数字资产所属的技术手段就是本篇要介绍的签名。而多重签名是对签名的扩展使用,给数字资产转移提供了安全保障和技术手段。本篇,从基本概念入手,

  • 我想创建一个签名并使用openssl验证它。我想有我的签名的十六进制输出。 这是我的密码 我得到这个错误: 如果我在创建签名的过程中删除了-hex,它就可以工作了。