2

1- Generating a Private Key, from the command line:

openssl genrsa -aes256 -out private.key 2048

  1. 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);
ses
  • 13,174
  • 31
  • 123
  • 226
  • 1
    Dupes https://stackoverflow.com/questions/52638604/ https://stackoverflow.com/questions/41934846/ https://stackoverflow.com/questions/7216969/ https://stackoverflow.com/questions/3243018/ . Short answer: use `openssl pkcs8 -topk8 -nocrypt`, or `openssl pkey`. Or generate with `keytool` or JCE in the first place instead of OpenSSL. @michalk: no, `genrsa` does not encrypt, but it uses 'traditional' (PKCS1) format not PKCS8 format. – dave_thompson_085 Jun 02 '19 at 06:58
  • So `-aes256` does not encrypt the key content while using `genrsa`? – Michał Krzywański Jun 02 '19 at 07:05
  • Maybe your Java code could use your key easier, if you put it into a .jks or .p12 keystore. – Lorinczy Zsigmond Jun 02 '19 at 17:51

1 Answers1

1

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

  1. To create a private-public keys:

    • openssl genrsa -out private.key 4096
    • openssl rsa -pubout -in private.key -out public.key
  2. 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.

ses
  • 13,174
  • 31
  • 123
  • 226