I'm trying to create an app that uses authentication with ecdsa keys but I faced with some problem with key generation and reading it. When I make request to the authentication controller it shows me such exception:
java.security.InvalidKeyException: IOException : algid parse error, not a sequence
That's what I did:
- I generated private key with this command:
$ openssl ecparam -name secp256k1 -genkey -noout -out private_key.pem
Then I got this pem key:
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIMdy2DTdd7ZF/oVjd69ddslzyy1GsBSuehz0uEGVYtk5oAcGBSuBBAAK
oUQDQgAEnZaAiTxwX93hzPMs4+VVJ1tGK1wv6SWN4Ac/59fQx6bBY0MO6VTzofna
gomVhx/xcyu7KQVmNVTgW51w7BSfNg==
-----END EC PRIVATE KEY-----
- I wrote a class that gets private key to use it later
RSAService.java
public class RSAService {
public static PrivateKey getPrivateKey(String fileName)
throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
return getPrivateKeyFromString(getKey(fileName));
}
private static String getKey(String fileName) throws IOException {
StringBuilder strKeyPem = new StringBuilder();
String line;
try (BufferedReader bf = new BufferedReader(new FileReader(fileName))) {
while ((line = bf.readLine()) != null) {
strKeyPem.append(line).append("\n");
}
}
return strKeyPem.toString();
}
private static PrivateKey getPrivateKeyFromString(String key)
throws NoSuchAlgorithmException, InvalidKeySpecException {
String privateKeyPem = key;
privateKeyPem = privateKeyPem.replace("-----BEGIN EC PRIVATE KEY-----", "");
privateKeyPem = privateKeyPem.replace("-----END PRIVATE KEY-----", "");
privateKeyPem = privateKeyPem.replace("\n", "");
byte[] encoded = Base64.decodeBase64(privateKeyPem);
KeyFactory kf = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
return kf.generatePrivate(keySpec); //Here's exception is throwing
}
}
- Then I use this class in JWTService to generate the jwt token:
JWTService.java
@Service
public class JWTService {
public String extractUsername(String token)
throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
return extractClaim(token, Claims::getSubject);
}
public <T> T extractClaim(String token, Function<Claims, T> claimResolver)
throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
final Claims claims = extractAllClaims(token);
return claimResolver.apply(claims);
}
public String generateToken(UserDetails userDetails)
throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
return generateToken(new HashMap<>(), userDetails);
}
public String generateToken(Map<String, Object> claims, UserDetails userDetails)
throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
PrivateKey privateKey = RSAService.getPrivateKey(PathConfig.PRIVATE_KEY_CONFIG);
return Jwts
.builder()
.setClaims(claims)
.setSubject(userDetails.getUsername())
.signWith(privateKey, SignatureAlgorithm.ES256)
.compact();
}
public boolean isTokenValid(String token, UserDetails userDetails)
throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
final String username = extractUsername(token);
return username.equals(userDetails.getUsername());
}
private Claims extractAllClaims(String token)
throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
return Jwts
.parserBuilder()
.setSigningKey(RSAService.getPublicKey(PathConfig.PUBLIC_KEY_CONFIG))
.build()
.parseClaimsJws(token)
.getBody();
}
}
So what can be the problem? If you know, please tell me, I'd really appreciate it!