Reputation: 13342
1- Generating a Private Key, from the command line:
openssl genrsa -aes256 -out private.key 2048
from java
, read it:
String privateKey = IOUtils.toString(TestJwtSecurityUtil.class.getResourceAsStream("/private.key"));
privateKey = privateKey.replace("-----BEGIN RSA PRIVATE KEY-----", "");
privateKey = privateKey.replace("-----END RSA PRIVATE KEY-----", "");
privateKey = privateKey.replaceAll("\\s+","");
byte[] encodedKey = DatatypeConverter.parseBase64Binary( privateKey );
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedKey);
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey pKey = kf.generatePrivate(keySpec); // fails
Got exception:
Exception in thread "main" java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : DerInputStream.getLength(): lengthTag=58, too big.
I tried to convert to base64:
byte[] encodedKey = DatatypeConverter.parseBase64Binary( encodedString );
PrivateKey pKey = kf.generatePrivate(keySpec); // fails
got:
Exception in thread "main" java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format
at java.base/sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:251)
Q: how to pass this? To make private key being read so in the end I could sing the JWT token:
final JwtBuilder builder = Jwts.builder().setId("id1")
....
.signWith(signatureAlgorithm, pKey);
Upvotes: 2
Views: 3067
Reputation: 13342
Yes, it is duplicate. But since I spent more than 1 h looking for it in SO site. Based on this reply, and bouncycastle's PEMParser. Thanks, @dave_thompson_085
To create a private-public keys:
then from java
--
final PrivateKey pKey = getPrivateKey();
final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.RS256; // private key to sign / public to confrim a sign
final JwtBuilder builder = Jwts.builder().setId("id1")
.setIssuedAt(now)
.setSubject(subject)
.setIssuer(issuer)
.setAudience("api")
.addClaims(Map.of(
"user_name", "test user",
"authorities", List.of("ROLE_USER"),
"scope", List.of("read", "write"),
"client_id", "test-client"
)
) .signWith(signatureAlgorithm, pKey);
String jwt = builder.compact();
where:
private static PrivateKey getPrivateKey() throws Exception {
val path = TestUtils.class.getResource("/").getPath();
final PEMParser pemParser = new PEMParser(new FileReader(path + "/private.key"));
final JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
final PEMKeyPair object = (PEMKeyPair) pemParser.readObject();
final KeyPair kp = converter.getKeyPair(object);
final PrivateKey pKey = kp.getPrivate();
return pKey;
}
Then to check, paste: generated jwt
to https://jwt.io/ (or any other tool) to see/check the content.
put a public.key content there to check the signature. To see that all is green.
Upvotes: 1