Skip to content
Advertisement

Parsing encrypted PKCS#8 encoded pem file programatically

I am having trouble figuring out how to properly read a private key of a pem file. I have gone through different topics on stackoverflow, but I couldn’t find the solution for it. What I want to achieve is reading an encrypted private key in pkcs#8 encoding file from a classpath and load it as a key-entry in a in memory keystore. Below is an example private key which I try to parse, the password is secret. It is purely created for sharing here, so it is not a private key which is used on a production machine.

I created it from a p12 file with the following command: openssl pkcs12 -in key-pair.p12 -out key-pair.pem

Valid example (throw-away) key-pair

JavaScript

I know BouncyCastle is able to parse it, but I want to avoid using additional libraries. So I am wondering if it is possible with just plain jdk or with some other lightweight libraries.

I am already able to parse private key with the following header/footer:

JavaScript

and

JavaScript

I already use the following snippet to accomplish that:

JavaScript

I also am required to handle asn.1 encoded private key. I could use BouncyCastle, but again I wanted to avoid it because I am curious for alternatives. I got inspired from this topic: https://stackoverflow.com/a/42733858/6777695 but DerInputStream and DerValue aren’t accessible anymore from jdk 11 onwards. And the sun packages should be avoided… So I discovered asn-one java library to parse asn.1 encoded private key, and it works quite well.

I have shared my full snippet of handling the other cases, so it will be easier to try out when someone wants to help me.

From the following article: ASN.1 key structures in DER and PEM I learned that a private key having the following header/footer: -----BEGIN ENCRYPTED PRIVATE KEY----- * -----END ENCRYPTED PRIVATE KEY----- is also an asn.1 encoded private key with the following structure:

JavaScript

I also tried the answers provided here How to read a password encrypted key with java? but those also didn’t work. However I am not quite sure how to parse it correctly to a java object and load it as a KeySpec. So any help is welcome!

======> Updated progress at 12-09-2020 based on the input of dave_thompson_085

JavaScript

Results into the following exception: java.security.InvalidKeyException: Wrong algorithm: DESede or TripleDES required on the statement cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);

======> Updated progress at 13-09-2020 based on the input of Michael Fehr

JavaScript

Advertisement

Answer

Your edited code gives an error “java.security.InvalidKeyException: Wrong key size” and that’s because you “read” the keyLength with this line:

JavaScript

With the given private key the length would be 1247 bits and that is not an allowed TripleDES length. You can fix it to (hardcoded):

JavaScript

Now we get a keyLength of 192 bit = 24 byte and that’s ok for an TripleDES-key but we receive a new error:

JavaScript

The reason for this behavior is the following line (commented out) that can get fixed with the 2 additional lines:

JavaScript

Now your code is successfully running and print outs the private key and the certificate:

JavaScript

Here is the full code that is running on Open Java 11:

JavaScript
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement