我们需要处理来自 API 网关的请求。用户的身份将通过 JWT 令牌传递并加密(通过私钥),我们收到公钥(Base64 格式)以对其进行验证。
目前我一直没有做到这一点。 我设法做的是加密,然后使用自己生成的私钥/公钥再次验证我自己的令牌:
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(2048);
kp = kpg.generateKeyPair();
//generate & sign simple token:
Map<String, Object> claims = new HashMap<>();
claims.put("id", "xxx");
claims.put("role", "user");
token = Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.RS256, kp.getPrivate()).compact();
//now sign the thing
Claims claims = Jwts.parser().setSigningKey(kp.getPublicKey()).parseClaimsJws(base64EncodedToken).getBody();
System.out.println(claims.get("id")); //gives me xxx as expected
这里没有问题。
下一步是外部化(文件)那些生成的密钥;例如:
out = new FileWriter("key.pub");
out.write(encoder.encodeToString(kp.getPublic().getEncoded()));
out.close();
然后不是使用 KeyPairGenerator,而是通过从 (Base64) 文件中读取公钥/私钥并对其进行解码来创建公钥/私钥:
public PrivateKey getPrivateKey() throws Exception {
String base64PrivateKey = new String(Files.readAllBytes(Paths.get(ClassLoader.getSystemResource("private.key").toURI())));
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec (Base64.getDecoder().decode(base64PrivateKey.getBytes()));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePrivate(keySpec);
}
public PublicKey getPublicKey() throws Exception {
String base64PublicKey = new String(Files.readAllBytes(Paths.get(ClassLoader.getSystemResource("public.key").toURI())));
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(base64PublicKey.getBytes()));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(keySpec);
}
当我再次运行相同的过程时(生成加密令牌并验证它):
<块引用>线程“main”io.jsonwebtoken.SignatureException 中的异常:JWT 签名与本地计算的签名不匹配。 JWT 有效性无法断言,不应信任。
我一定遗漏了什么,因为我对加密几乎没有经验。
附言文件是 1 个衬里,如下所示:
<块引用>public.key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxetc3258...
<块引用>private.key: MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEA...