使用 JWT 和 RSA 解码 Id 令牌
Decode IdToken using JJWT with RSA
我的客户发送给我一个 JWT,我需要使用他们的 public 密钥验证这个 JWT。
我正在使用 Java 和 JJWT 框架来验证此令牌。
我知道使用 HS256 解码此令牌,但我不知道使用 RS256。
他们的配置是:
在这里编辑以改进我的问题。
我正在使用的 jjwt 解析示例:
Claims String secret = "-----BEGIN CERTIFICATE-----myx5ckey-----END CERTIFICATE-----"
byte[] dataBytes = Base64.getEncoder().encode(secret.getBytes());
byte[] byteKey = Base64.getDecoder().decode(dataBytes);
X509EncodedKeySpec X509publicKey = new X509EncodedKeySpec(byteKey);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey publicKey = kf.generatePublic(X509publicKey);
Claims body = null;
body = Jwts.parser().setSigningKey(publicKey.getEncoded())
.parseClaimsJws(idToken)
.getBody();
java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format
at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:205)
如何使用我显示的 JWKS 信息验证收到的令牌? (上图)
tldr;需要按照三个步骤
- 从 JWK 中提取 public 密钥可能正在通过发现文档或任何其他方式进行。
- 按照JWS specification
所述提取 JWS 签名和 JWS 签名输入
- 将 public 密钥、JWS 签名和 JWS 签名输入传递给签名验证器
根据库的不同,步骤 2 和 3 可以一步完成。!
长答案
要验证您必须遵循 JWS 规范。
协议 RFC7515 explains how to create JWT's MAC needed to validate the token. Appendix 2 中定义的 JWS 规范解释了如何使用 RS256 创建 MAC 并验证它。
使用发现信息,您必须识别 public 密钥。现在您已经收到 JWK 的关键详细信息。根据 x5x,
上的 JWK 协议定义
The "x5c" (X.509 certificate chain) parameter contains a chain of one
or more PKIX certificates
所以基本上你在 JWK 中有 public 键。现在您需要将 x5x 的编码字符串转换为 public 密钥。为此,请检查此已回答 question.
构建 public 密钥后,使用它来验证令牌。以下是从规范中提取的内容。
Since the "alg" Header Parameter is "RS256", we validate the
RSASSA- PKCS1-v1_5 SHA-256 digital signature contained in the JWS
Signature.
Validating the JWS Signature is a bit different from the previous example. We pass the public key (n, e), the JWS Signature (which is base64url decoded from the value encoded in the JWS representation), and the JWS Signing Input (which is the initial substring of the JWS Compact Serialization representation up until but not including the second period character) to an RSASSA-PKCS1-v1_5 signature verifier that has been configured to use the SHA-256 hash function.
为了验证,最好使用库。作为参考,这里是 link 如何使用 nimbus
完成的
我解决了我的问题。
String secret2 = "myX5c";
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Certificate certificate = cf.generateCertificate(new ByteArrayInputStream(DatatypeConverter.parseBase64Binary(secret2)));
PublicKey publicKey = certificate.getPublicKey();
Claims body = null;
body = Jwts.parser().setSigningKey(publicKey)
.parseClaimsJws(idToken)
.getBody();
@KcDoD 感谢您的提示。
我的客户发送给我一个 JWT,我需要使用他们的 public 密钥验证这个 JWT。 我正在使用 Java 和 JJWT 框架来验证此令牌。 我知道使用 HS256 解码此令牌,但我不知道使用 RS256。
他们的配置是:
在这里编辑以改进我的问题。 我正在使用的 jjwt 解析示例:
Claims String secret = "-----BEGIN CERTIFICATE-----myx5ckey-----END CERTIFICATE-----"
byte[] dataBytes = Base64.getEncoder().encode(secret.getBytes());
byte[] byteKey = Base64.getDecoder().decode(dataBytes);
X509EncodedKeySpec X509publicKey = new X509EncodedKeySpec(byteKey);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey publicKey = kf.generatePublic(X509publicKey);
Claims body = null;
body = Jwts.parser().setSigningKey(publicKey.getEncoded())
.parseClaimsJws(idToken)
.getBody();
java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format
at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:205)
如何使用我显示的 JWKS 信息验证收到的令牌? (上图)
tldr;需要按照三个步骤
- 从 JWK 中提取 public 密钥可能正在通过发现文档或任何其他方式进行。
- 按照JWS specification 所述提取 JWS 签名和 JWS 签名输入
- 将 public 密钥、JWS 签名和 JWS 签名输入传递给签名验证器
根据库的不同,步骤 2 和 3 可以一步完成。!
长答案
要验证您必须遵循 JWS 规范。
协议 RFC7515 explains how to create JWT's MAC needed to validate the token. Appendix 2 中定义的 JWS 规范解释了如何使用 RS256 创建 MAC 并验证它。
使用发现信息,您必须识别 public 密钥。现在您已经收到 JWK 的关键详细信息。根据 x5x,
上的 JWK 协议定义The "x5c" (X.509 certificate chain) parameter contains a chain of one or more PKIX certificates
所以基本上你在 JWK 中有 public 键。现在您需要将 x5x 的编码字符串转换为 public 密钥。为此,请检查此已回答 question.
构建 public 密钥后,使用它来验证令牌。以下是从规范中提取的内容。
Since the "alg" Header Parameter is "RS256", we validate the RSASSA- PKCS1-v1_5 SHA-256 digital signature contained in the JWS Signature.
Validating the JWS Signature is a bit different from the previous example. We pass the public key (n, e), the JWS Signature (which is base64url decoded from the value encoded in the JWS representation), and the JWS Signing Input (which is the initial substring of the JWS Compact Serialization representation up until but not including the second period character) to an RSASSA-PKCS1-v1_5 signature verifier that has been configured to use the SHA-256 hash function.
为了验证,最好使用库。作为参考,这里是 link 如何使用 nimbus
完成的我解决了我的问题。
String secret2 = "myX5c";
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Certificate certificate = cf.generateCertificate(new ByteArrayInputStream(DatatypeConverter.parseBase64Binary(secret2)));
PublicKey publicKey = certificate.getPublicKey();
Claims body = null;
body = Jwts.parser().setSigningKey(publicKey)
.parseClaimsJws(idToken)
.getBody();
@KcDoD 感谢您的提示。