I have an unencrypted PKCS8 encoded file that represents a Private Key. It can be any of these private key types - RSA, DSA or EC. I viewed these files in an ASN1 decoder (https://lapo.it/asn1js/) and I could see the type (RSA, DSA or EC) in the data.
Is there a way to read the PKC8 private key data into the correct Private Key Java object without specifying the key type in code like this -
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(pkcs8key);
KeyFactory factory = KeyFactory.getInstance("RSA"); // Avoid "RSA" here?
PrivateKey privateKey = factory.generatePrivate(spec);
Is there a way to avoid specifying the algorithm in KeyFactory.getInstance("RSA")
? Shouldn't this be determined from the PKCS8EncodedKeySpec
since it is available in the PKCS8 data?
Sample unencrypted PKCS8 data and their ASN1 decodings which show the key type -
DSA - link
EC - link
RSA - link
This can be achieved with the help of BouncyCastle APIs -
/** Read a PKCS#8 format private key. */
private static PrivateKey readPrivateKey(InputStream input)
throws IOException, GeneralSecurityException {
try {
byte[] buffer = new byte[4096];
int size = input.read(buffer);
byte[] bytes = Arrays.copyOf(buffer, size);
/* Check to see if this is in an EncryptedPrivateKeyInfo structure. */
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(bytes);
/*
* Now it's in a PKCS#8 PrivateKeyInfo structure. Read its Algorithm
* OID and use that to construct a KeyFactory.
*/
ASN1InputStream bIn = new ASN1InputStream(new ByteArrayInputStream(spec.getEncoded()));
PrivateKeyInfo pki = PrivateKeyInfo.getInstance(bIn.readObject());
String algOid = pki.getPrivateKeyAlgorithm().getAlgorithm().getId();
return KeyFactory.getInstance(algOid).generatePrivate(spec);
} finally {
input.close();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With