Пара ключей RSA не работает
Вот мое поколение ключей:
KeyPairGenerator keyGen = null;
try {
keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(1024);
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String publicKey= Base64.getEncoder().encodeToString(keyGen.genKeyPair().getPublic().getEncoded());
String privateKey = Base64.getEncoder().encodeToString(keyGen.genKeyPair().getPrivate().getEncoded());}
вот мой подписанный код генерации токена
private String generateRSASignedToken(JWTClaimsSet claimsSet) {
SignedJWT signedJwt = new SignedJWT(new JWSHeader(JWSAlgorithm.RS256), claimsSet);
RSASSASigner signer = new RSASSASigner(getPrivateKey());
String token= null;
try {
signedJwt.sign(signer);
token = signedJwt.serialize();
} catch (JOSEException e) {
e.printStackTrace();
}
return token;
}
получение открытого и закрытого ключа
private RSAPrivateKey getPrivateKey() {
java.security.Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
try(InputStream stream = getClass().getClassLoader().getResourceAsStream("private.key")){
String privatekey = IOUtils.toString(stream, Charset.defaultCharset().toString());
System.out.println("after: "+privatekey);
byte[] key = Base64.getDecoder().decode(privatekey);
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(key);
KeyFactory kf = KeyFactory.getInstance("RSA");
return (RSAPrivateKey) kf.generatePrivate(spec);}
catch (Exception e) {
e.printStackTrace();
return null;
}
}
private RSAPublicKey getPublicKey(){
try(InputStream stream = getClass().getClassLoader().getResourceAsStream("public.key")){
String publickey = IOUtils.toString(stream, Charset.defaultCharset().toString());
System.out.println("after: "+publickey);
byte[] key = Base64.getDecoder().decode(publickey);
X509EncodedKeySpec spec = new X509EncodedKeySpec(key);
KeyFactory kf = KeyFactory.getInstance("RSA");
return (RSAPublicKey) kf.generatePublic(spec);}
catch (Exception e) {
e.printStackTrace();
return null;
}}
проверка токена:
String token = generateRSASignedToken(claimsSet);
JWSVerifier verifier = new RSASSAVerifier(getPublicKey());
SignedJWT jwt=null;
try {
jwt = SignedJWT.parse(token);
System.out.println(jwt.verify(verifier));
} catch (ParseException | JOSEException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
все выглядит отлично от части генерации токена до получения открытого и закрытого ключа, но часть проверки не работает. Это печатает ложь для сгенерированной пары ключей. Он работал нормально с парой ключей, которую я получил от онлайн-инструмента (который я не могу использовать из-за проблем с лицензированием), но не тогда, когда я генерировал ключи.
1 ответ
Проблема здесь:
String publicKey = Base64.getEncoder().encodeToString(keyGen.genKeyPair().getPublic().getEncoded());
String privateKey = Base64.getEncoder().encodeToString(keyGen.genKeyPair().getPrivate().getEncoded());
Каждый раз, когда вы звоните genKeyPair()
новая пара ключей генерируется. таким образом publicKey
а также privateKey
приходят из разных и несвязанных пар ключей. Решение состоит в том, чтобы просто сохранить только что сгенерированную пару ключей, например
KeyPair kp = keyGen.genKeyPair();
String publicKey = Base64.getEncoder().encodeToString(kp.getPublic().getEncoded());
String privateKey = Base64.getEncoder().encodeToString(kp.getPrivate().getEncoded());
ПРИМЕЧАНИЕ: могут быть другие проблемы с кодом, это первый, который я заметил.