Rahs
Rahs

Reputation: 99

How can I create a Java KeyStore from an existing set of certificates and keys without using command line tools?

I obtain a randomly generated RSA certificate and private key as strings from another service, and I would like to use those strings to create a Java KeyStore. All of the examples I see involve saving these strings to files, using the openssl and keytool command line tools to create the keystore on disk, and then loading the resulting KeyStore into memory (like here). However, it makes more sense for my purposes to create the KeyStore entirely in memory.

To that end, I am trying to use the Java Security API. I am able to convert the certificate string into an instance of the java.security.cert.Certificate class, but I am unable to convert the private key into an instance of java.security.PrivateKey. Here's method I am trying to create:

private PrivateKey generatePrivateKey (String newKey) 
    throws NoSuchAlgorithmException,
    InvalidKeySpecException, IOException {

//Configuring the KeyFactory to use RSA
KeyFactory kf = KeyFactory.getInstance("RSA");

//Convert the key string to a byte array
byte[] keyBytes = newKey.getBytes();

KeySpec ks = new PKCS8EncodedKeySpec(keyBytes);

PrivateKey key = kf.generatePrivate(ks);
return key;
}    

Where the value of newKey is something like "-----BEGIN RSA PRIVATE KEY-----\nMIIEow...gNK3x\n-----END RSA PRIVATE KEY-----".

When I run the code, I receive the following exception:

java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format
at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:217)
at java.security.KeyFactory.generatePrivate(KeyFactory.java:372)
... 30 more
Caused by: java.security.InvalidKeyException: invalid key format
at sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:341)
at sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:367)
at sun.security.rsa.RSAPrivateCrtKeyImpl.<init>(RSAPrivateCrtKeyImpl.java:91)
at sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(RSAPrivateCrtKeyImpl.java:75)
at sun.security.rsa.RSAKeyFactory.generatePrivate(RSAKeyFactory.java:316)
at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:213)
... 32 more

This particular error is very similar to this stackoverflow question, and I would be grateful if that question were resolved, but I also want to know if my higher level goal (creating a JKS programmatically and solely in memory using Java) is feasible, and if so, whether I am on the right path.

Upvotes: 2

Views: 1411

Answers (1)

JohnnyAW
JohnnyAW

Reputation: 2876

you need to decode base64 if your key is in the base64 representation:

KeySpec ks = new PKCS8EncodedKeySpec(Base64.decodeBase64(newKey));

you can use org.apache.commons.codec.binary.Base64 to do this.

if you want to generate keyPair you can you this code:

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(1024);
KeyPair keyPair = keyPairGenerator.genKeyPair();

// extract the encoded private key, this is an unencrypted PKCS#8 private key
byte[] encodedprivkey = keyPair.getPrivate().getEncoded();
System.out.println(Base64.encodeBase64String(encodedprivkey));

Upvotes: 2

Related Questions