CryptoAPI PRIVATEKEYBLOB to Java PrivateKey Converter


MSPrivKeytoJKey.java is a simply utility Java class which reads a Windows CryptoAPI PRIVATEKEYBLOB file, parses the PRIVATEKEYBLOB and instantiates an RSA PrivateKey. The utility also dumps the privatekey components and, optionally, writes a pkcs#8 encoded PrivateKeyInfo file, and optionally writes an encoded SubjectPublicKeyInfo public key file:

     java MSPrivKeytoJKey  myPRIVATEKEYBLOBfile   [outputPKCS#8file]  [SubjectPublicKeyInfo_pubkey]
Since Java generally reads/writes multi-byte data in big-endian format, but the PRIVATEKEYBLOB has members formatted in little-endian order, the parsing in Java must reformat the data and reverse byte arrays.

The main worker method for the conversion is

  public static PrivateKey getPrivateKey (byte[] msprivatekeyblob)
The PRIVATEKEYBLOB file is parsed according to the PRIVATEKEYBLOB specification. The Java PrivateKey is created using:
     RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec(... BigInteger privatekey components ..);
     KeyFactory keyFactory = KeyFactory.getInstance("RSA");
     PrivateKey privKey = keyFactory.generatePrivate(privKeySpec);

Asymmetric private keys are often represented externally in the ASN.1 encoded PKCS#8 PrivateKeyInfo format. Java 2 provides convenient creation of this encoded form using PrivateKey.getEncoded(). Also, OpenSSL supports PKCS#8 and conversion from the "traditional" SSLeay PEM private key format to PKCS#8. In the default Java 2 keystore implementation, RSA keypairs contained in Java keystores are always associated with a certificate (chain). RSA keypairs specified in a Windows PRIVATEKEYBLOB are raw keypairs, with no associated certificate information (although the CryptoAPI keycontainer from which the PRIVATEKEYBLOB may have been exported may be linked to an associated certificate validating the corresponding public RSA key). The Java PrivateKey instantiated here can therefore not be imported into a standard Java 2 keystore. However, the PrivateKey can be used directly for any operations requiring an RSA PrivateKey. In Windows CryptoAPI, RSA keypairs can be exported and imported in the specialized PRIVATEKEYBLOB format, in both unencrypted and encrypted forms.

Java 2 v1.5+ also supports creating more secure PKCS#8 EncryptedPrivateKeyInfo encoding from PKCS#8 unencrypted PrivateKeyInfo data. For an example using PBEWithSHA1AndDESede encryption see PKCS #8 EncryptedPrivateKeyInfo encryption (PBE).

See also: PKCS#8 PrivateKeyInfo to CryptoAPI PRIVATEKEYBLOB converter