只能为 HMAC 签名指定密钥字节。请指定 PublicKey 或 PrivateKey 实例
Key bytes can only be specified for HMAC signatures. Please specify a PublicKey or PrivateKey instance
我正在尝试读取从 Google OpenID Connect 的 Id 令牌生成的 Json Web 令牌 (JWT),以便获取声明并使用 jjwt 库进行验证。我已经尝试了几种方法来使用下面的代码修复它。
String publicKeyFromJsonFile = "-----BEGIN PUBLIC KEY-----xxxxxxx-----END PUBLIC KEY-----"
Claims claims = Jwts.parser()
.setSigningKey(publicKeyFromJsonFile)
.parseClaimsJws(jwt).getBody();
System.out.println(claims);
但我收到此错误:
java.lang.IllegalArgumentException: Key bytes can only be specified for HMAC signatures. Please specify a PublicKey or PrivateKey instance
请问正确的方法是什么?
一个好的方法是使用 JWT.IO 网页手动验证令牌 - 如 my article - then to apply the equivalent code 中所述 - 尽管我的代码是 NodeJS。
对您如何手动验证 ID 令牌感兴趣 -
您能否解释一下涉及哪些客户端和 API - 可能有更标准的方法来实现您的目标。
我想我已经能够通过将 publicKey 解析为 RSAPublicKey
来解决问题。以下是我如何处理它的细节。
public static Optional<RSAPublicKey> getParsedPublicKey(){
// public key content...excluding '---PUBLIC KEY---' and '---END PUBLIC KEY---'
String PUB_KEY =System.getenv("PUBLIC_KEY") ;
// removes white spaces or char 20
String PUBLIC_KEY = "";
if (!PUB_KEY.isEmpty()) {
PUBLIC_KEY = PUB_KEY.replace(" ", "");
}
try {
byte[] decode = com.google.api.client.util.Base64.decodeBase64(PUBLIC_KEY);
X509EncodedKeySpec keySpecX509 = new X509EncodedKeySpec(decode);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPublicKey pubKey = (RSAPublicKey) keyFactory.generatePublic(keySpecX509);
return Optional.of(pubKey);
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
e.printStackTrace();
System.out.println("Exception block | Public key parsing error ");
return Optional.empty();
}
希望对您有所帮助:)。
这可以像下面那样完成,使用私钥签名生成令牌并使用 public 密钥
解析声明
@Configuration
public class KeyGeneratorConfig {
@Value("${jwt.privateKey}")
private String privateKey; //Encoded private key string
@Value("${jwt.publicKey}")
private String publicKey;//Encoded public key string
@Bean
public PrivateKey generatePrivateKey() throws NoSuchAlgorithmException, InvalidKeySpecException {
KeyFactory kf = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec privKeySpecPKCS8 = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey));
return kf.generatePrivate(privKeySpecPKCS8);
}
@Bean
public PublicKey generatePublicKey() throws NoSuchAlgorithmException, InvalidKeySpecException {
KeyFactory kf = KeyFactory.getInstance("RSA");
X509EncodedKeySpec pubKeySpecX509EncodedKeySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKey));
return kf.generatePublic(pubKeySpecX509EncodedKeySpec);
}
}
生成令牌和解析可以像这样完成
@Autowired
private PublicKey publicKey;
@Autowired
private PrivateKey privateKey;
private String doGenerateToken(Map claims) {
return Jwts.builder()
.setClaims(claims)
.setExpiration(generateExpirationDate("token"))
.signWith(SignatureAlgorithm.RS512, privateKey)
.compact();
}
public Claims getClaimsFromToken(String token) throws ExpiredJwtException, UnsupportedJwtException,
MalformedJwtException, SignatureException, IllegalArgumentException {
Claims claims;
claims = Jwts.parser()
.setSigningKey(publicKey)
.parseClaimsJws(token)
.getBody();
return claims;
}
我正在尝试读取从 Google OpenID Connect 的 Id 令牌生成的 Json Web 令牌 (JWT),以便获取声明并使用 jjwt 库进行验证。我已经尝试了几种方法来使用下面的代码修复它。
String publicKeyFromJsonFile = "-----BEGIN PUBLIC KEY-----xxxxxxx-----END PUBLIC KEY-----"
Claims claims = Jwts.parser()
.setSigningKey(publicKeyFromJsonFile)
.parseClaimsJws(jwt).getBody();
System.out.println(claims);
但我收到此错误:
java.lang.IllegalArgumentException: Key bytes can only be specified for HMAC signatures. Please specify a PublicKey or PrivateKey instance
请问正确的方法是什么?
一个好的方法是使用 JWT.IO 网页手动验证令牌 - 如 my article - then to apply the equivalent code 中所述 - 尽管我的代码是 NodeJS。
对您如何手动验证 ID 令牌感兴趣 - 您能否解释一下涉及哪些客户端和 API - 可能有更标准的方法来实现您的目标。
我想我已经能够通过将 publicKey 解析为 RSAPublicKey
来解决问题。以下是我如何处理它的细节。
public static Optional<RSAPublicKey> getParsedPublicKey(){
// public key content...excluding '---PUBLIC KEY---' and '---END PUBLIC KEY---'
String PUB_KEY =System.getenv("PUBLIC_KEY") ;
// removes white spaces or char 20
String PUBLIC_KEY = "";
if (!PUB_KEY.isEmpty()) {
PUBLIC_KEY = PUB_KEY.replace(" ", "");
}
try {
byte[] decode = com.google.api.client.util.Base64.decodeBase64(PUBLIC_KEY);
X509EncodedKeySpec keySpecX509 = new X509EncodedKeySpec(decode);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPublicKey pubKey = (RSAPublicKey) keyFactory.generatePublic(keySpecX509);
return Optional.of(pubKey);
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
e.printStackTrace();
System.out.println("Exception block | Public key parsing error ");
return Optional.empty();
}
希望对您有所帮助:)。
这可以像下面那样完成,使用私钥签名生成令牌并使用 public 密钥
解析声明 @Configuration
public class KeyGeneratorConfig {
@Value("${jwt.privateKey}")
private String privateKey; //Encoded private key string
@Value("${jwt.publicKey}")
private String publicKey;//Encoded public key string
@Bean
public PrivateKey generatePrivateKey() throws NoSuchAlgorithmException, InvalidKeySpecException {
KeyFactory kf = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec privKeySpecPKCS8 = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey));
return kf.generatePrivate(privKeySpecPKCS8);
}
@Bean
public PublicKey generatePublicKey() throws NoSuchAlgorithmException, InvalidKeySpecException {
KeyFactory kf = KeyFactory.getInstance("RSA");
X509EncodedKeySpec pubKeySpecX509EncodedKeySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKey));
return kf.generatePublic(pubKeySpecX509EncodedKeySpec);
}
}
生成令牌和解析可以像这样完成
@Autowired
private PublicKey publicKey;
@Autowired
private PrivateKey privateKey;
private String doGenerateToken(Map claims) {
return Jwts.builder()
.setClaims(claims)
.setExpiration(generateExpirationDate("token"))
.signWith(SignatureAlgorithm.RS512, privateKey)
.compact();
}
public Claims getClaimsFromToken(String token) throws ExpiredJwtException, UnsupportedJwtException,
MalformedJwtException, SignatureException, IllegalArgumentException {
Claims claims;
claims = Jwts.parser()
.setSigningKey(publicKey)
.parseClaimsJws(token)
.getBody();
return claims;
}