JSON 网络签名 (Ninbus-JOSE-JWT)
JSON Web Signature (Ninbus-JOSE-JWT)
我想用 JSON Web 签名 (JWS) 做一个项目,我想发送用于签名的证书的 public 密钥,以便在收到消息后进行验证使用此 public 键。我正在使用 Ninbus JOS JWT 库。我可以签署 JSON 对象并且可以看到 public 密钥,但我无法正确验证它。
这是代码:
// 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!
_rsaPublicKey 是:"Sun RSA public key, 2048 bits",但是当我从 JWK (_rsaPublicKey2) 获取它时,我得到 "Sun RSA public key, 3696 bits",我不知道为什么。
谢谢!
在接收方,您是否在信任密钥之前验证 X.509 证书颁发者、主题和链?在收件人确定它可以信任 JWS 中包含的证书之前,不得尝试签名验证。
另一个注意事项:不要在 JWS header 中包含 public JWK。这应该只用于 ECDH 中的临时 public 密钥(用于 JWE 的不同算法)。在 JWS header 中传递证书链就足够了,但在使用其 public 密钥之前,您必须验证它/查明证书是否可信。
图书馆不会验证/查明证书是否可以为您信任!
如果第二次签名验证失败,则可能是用于签署 JWS 的密钥与 X.509 证书附带的密钥不同(如不同报告长度所建议的 - 2048 位与 3696 位位)。
我想用 JSON Web 签名 (JWS) 做一个项目,我想发送用于签名的证书的 public 密钥,以便在收到消息后进行验证使用此 public 键。我正在使用 Ninbus JOS JWT 库。我可以签署 JSON 对象并且可以看到 public 密钥,但我无法正确验证它。 这是代码:
// 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!
_rsaPublicKey 是:"Sun RSA public key, 2048 bits",但是当我从 JWK (_rsaPublicKey2) 获取它时,我得到 "Sun RSA public key, 3696 bits",我不知道为什么。
谢谢!
在接收方,您是否在信任密钥之前验证 X.509 证书颁发者、主题和链?在收件人确定它可以信任 JWS 中包含的证书之前,不得尝试签名验证。
另一个注意事项:不要在 JWS header 中包含 public JWK。这应该只用于 ECDH 中的临时 public 密钥(用于 JWE 的不同算法)。在 JWS header 中传递证书链就足够了,但在使用其 public 密钥之前,您必须验证它/查明证书是否可信。
图书馆不会验证/查明证书是否可以为您信任!
如果第二次签名验证失败,则可能是用于签署 JWS 的密钥与 X.509 证书附带的密钥不同(如不同报告长度所建议的 - 2048 位与 3696 位位)。