PKCS#8 PrivateKeyInfo to CryptoAPI PRIVATEKEYBLOB & XML RSA key Converter


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 (PrivateKey.getEncoded()). Also, OpenSSL supports PKCS#8 and conversion from the "traditional" SSLeay PEM private key format to PKCS#8. In Windows CryptoAPI, RSA keypairs can be exported and imported in the specialized PRIVATEKEYBLOB format, in both unencrypted and encrypted forms. .NET 1.1 can use an XML-encoded public or private key string (the private key data is not protected however) using RSACryptoServiceProvider .From XmlString() to construct an RSA object for RSA decryption, or signature verification.

PvkConvert.java is a simply utility Java class which reads a PKCS#8 encoded PrivateKeyInfo file, instantiates a RSAPrivateCrtKey instance using an RSA Keyfactory, extracts the RSA private key components and writes:

Usage:
      java   PvkConvert  PKCS#8PrivateKeyInfo_File
Java also supports easily instantiating private keys directly from Java keystore files. 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.
For XML encoded RSA keys (both public and private), the b64 encoded elements represent the key components (modulus, exponent, P, Q .. etc.) in big-endian order. Any high-order zero bytes (most significant) in the key components byte[] data extracted by Java must be removed before before encoding.

The class contains five static methods:

  private static byte[]  privatekeyinfoToPrivatekeyblob(byte[] encodedPrivkey,  int keyspec)

  private static byte[]  toPublickeyblob(byte[] modulus,  int pubexp, int keyspec)

  private static String  privatekeyinfoToXMLRSAPriKey(byte[] encodedPrivkey) 

  private static String  privatekeyinfoToXMLRSAPubKey(byte[] encodedPrivkey) 

  private static void dumpRSAPrivatekey(byte[] encodedPrivkey)

The first method returns a CryptoAPI PRIVATEKEYBLOB from the PKCS#8 PrivateKeyInfo (byte[] encodedPrivkey).
The second method returns a CryptoAPI PUBLICKEYBLOB from the already acquired modulus (with bytes already reversed) and public exponent.
The PRIVATEKEYBLOB file is constructed according to the PRIVATEKEYBLOB specification.
The PUBLICKEYBLOB file is constructed according to the PUBLICKEYBLOB specification.
The third and fourth methods return an XML-encoded RSA private and public key respectively, for .NET 1.1+ usage.
The fifth method simply dumps the RSA private key components as decimal numbers, and the corresponding (big-endian) byte array values.

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: CryptoAPI PRIVATEKEYBLOB to Java PrivateKey converter