PKCS #8 / OpenSSL Encrypted Keys

Java 1.3 Compatible! (with jce1_2_2.jar) (or bcprov-jdk13.jar)

Commons-SSL includes support for extracting private keys from PKCS #8 files. We also support the OpenSSL formats ("traditional SSLeay"). The private keys can be in PEM (base64) or DER (raw ASN.1 - a binary format).

The code works with Java 1.3 (+JCE), 1.4, 5.0, 6.0, but not all of the ciphers and hashes are available until Java 5.0 (unless you use BouncyCastle). Fortunately the most common formats [OpenSSL MD5 with 3DES], [PKCS #8 V1.5 MD5 with DES], [PKCS #8 V2.0 HmacSHA1 with 3DES] work with all versions of Java, including Java 1.3.

pkcs8 example:

FileInputStream in = new FileInputStream( "/path/to/pkcs8_private_key.der" );

// If the provided InputStream is encrypted, we need a password to decrypt
// it. If the InputStream is not encrypted, then the password is ignored
// (can be null).  The InputStream can be DER (raw ASN.1) or PEM (base64).
PKCS8Key pkcs8 = new PKCS8Key( in, "changeit".toCharArray() );

// If an unencrypted PKCS8 key was provided, then this actually returns
// exactly what was originally passed in (with no changes).  If an OpenSSL
// key was provided, it gets reformatted as PKCS #8 first, and so these
// bytes will still be PKCS #8, not OpenSSL.
byte[] decrypted = pkcs8.getDecryptedBytes();
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec( decrypted );

// A Java PrivateKey object is born.
PrivateKey pk = null;
if ( pkcs8.isDSA() )
  pk = KeyFactory.getInstance( "DSA" ).generatePrivate( spec );
else if ( pkcs8.isRSA() )
  pk = KeyFactory.getInstance( "RSA" ).generatePrivate( spec );

// For lazier types (like me):
pk = pkcs8.getPrivateKey();

Both RSA and DSA keys are supported. Here is a list of supported formats:

Here are links to the raw samples and test results:

  1. 2048 Bit RSA
  2. 2048 Bit DSA

The samples were all generated using OpenSSL's rsa, genrsa, dsa, gendsa, dsaparam and pkcs8 commands. We're curious to know if PKCS #8 keys created by other programs will also work, but OpenSSL is all we have to play with at the moment.

The password to decrypt the samples is always "changeit", and they all have the same RSA or DSA key.