org.apache.commons.ssl
Class PKCS8Key

java.lang.Object
  extended by org.apache.commons.ssl.PKCS8Key

public class PKCS8Key
extends Object

Utility for decrypting PKCS8 private keys. Way easier to use than javax.crypto.EncryptedPrivateKeyInfo since all you need is the byte[] array and the password. You don't need to know anything else about the PKCS8 key you pass in.

Can handle base64 PEM, or raw DER. Can handle PKCS8 Version 1.5 and 2.0. Can also handle OpenSSL encrypted or unencrypted private keys (DSA or RSA).

The PKCS12 key derivation (the "pkcs12()" method) comes from BouncyCastle.

Since:
7-Nov-2006
Author:
Credit Union Central of British Columbia, www.cucbc.com, juliusdavies@cucbc.com, bouncycastle.org

Nested Class Summary
static class PKCS8Key.DecryptResult
           
 
Field Summary
private  byte[] decryptedBytes
           
static String DSA_OID
           
private  boolean isDSA
           
private  boolean isRSA
           
private  int keySize
           
static String OPENSSL_DSA
           
static String OPENSSL_RSA
           
static String PKCS8_ENCRYPTED
           
static String PKCS8_UNENCRYPTED
           
private  PrivateKey privateKey
           
static String RSA_OID
           
private  String transformation
           
 
Constructor Summary
PKCS8Key(byte[] encoded, char[] password)
           
PKCS8Key(ByteArrayInputStream in, char[] password)
           
PKCS8Key(InputStream in, char[] password)
           
 
Method Summary
private static boolean allZeroes(byte[] b)
           
static PKCS8Key.DecryptResult decrypt(String cipher, String mode, DerivedKey dk, boolean des2, byte[] iv, byte[] encryptedBytes)
           
private static PKCS8Key.DecryptResult decryptPKCS8(ASN1Structure pkcs8, char[] password)
           
static DerivedKey deriveKeyPKCS12(char[] password, byte[] salt, int iterations, int keySizeInBits, int ivSizeInBits, MessageDigest md)
           
static DerivedKey deriveKeyV1(byte[] password, byte[] salt, int iterations, int keySizeInBits, int ivSizeInBits, MessageDigest md)
           
static DerivedKey deriveKeyV2(byte[] password, byte[] salt, int iterations, int keySizeInBits, int ivSizeInBits, Mac mac)
           
static byte[] encode(DEREncodable der)
           
static byte[] formatAsPKCS8(byte[] privateKey, String oid, ASN1Structure pkcs8)
           
static Cipher generateCipher(String cipher, String mode, DerivedKey dk, boolean des2, byte[] iv, boolean decryptMode)
           
 byte[] getDecryptedBytes()
           
 int getKeySize()
           
 PrivateKey getPrivateKey()
           
 PublicKey getPublicKey()
           
 String getTransformation()
           
 boolean isDSA()
           
 boolean isRSA()
           
static void main(String[] args)
           
private static PKCS8Key.DecryptResult opensslDecrypt(PEMItem item, char[] password)
           
private static byte[] pkcs12(int idByte, int n, byte[] salt, byte[] password, int iterationCount, MessageDigest md)
          This PKCS12 key derivation code comes from BouncyCastle.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

RSA_OID

public static final String RSA_OID
See Also:
Constant Field Values

DSA_OID

public static final String DSA_OID
See Also:
Constant Field Values

PKCS8_UNENCRYPTED

public static final String PKCS8_UNENCRYPTED
See Also:
Constant Field Values

PKCS8_ENCRYPTED

public static final String PKCS8_ENCRYPTED
See Also:
Constant Field Values

OPENSSL_RSA

public static final String OPENSSL_RSA
See Also:
Constant Field Values

OPENSSL_DSA

public static final String OPENSSL_DSA
See Also:
Constant Field Values

privateKey

private final PrivateKey privateKey

decryptedBytes

private final byte[] decryptedBytes

transformation

private final String transformation

keySize

private final int keySize

isDSA

private final boolean isDSA

isRSA

private final boolean isRSA
Constructor Detail

PKCS8Key

public PKCS8Key(InputStream in,
                char[] password)
         throws GeneralSecurityException,
                IOException
Parameters:
in - pkcs8 file to parse (pem or der, encrypted or unencrypted)
password - password to decrypt the pkcs8 file. Ignored if the supplied pkcs8 is already unencrypted.
Throws:
GeneralSecurityException - If a parsing or decryption problem occured.
IOException - If the supplied InputStream could not be read.

PKCS8Key

public PKCS8Key(ByteArrayInputStream in,
                char[] password)
         throws GeneralSecurityException
Parameters:
in - pkcs8 file to parse (pem or der, encrypted or unencrypted)
password - password to decrypt the pkcs8 file. Ignored if the supplied pkcs8 is already unencrypted.
Throws:
GeneralSecurityException - If a parsing or decryption problem occured.

PKCS8Key

public PKCS8Key(byte[] encoded,
                char[] password)
         throws GeneralSecurityException
Parameters:
encoded - pkcs8 file to parse (pem or der, encrypted or unencrypted)
password - password to decrypt the pkcs8 file. Ignored if the supplied pkcs8 is already unencrypted.
Throws:
GeneralSecurityException - If a parsing or decryption problem occured.
Method Detail

isRSA

public boolean isRSA()

isDSA

public boolean isDSA()

getTransformation

public String getTransformation()

getKeySize

public int getKeySize()

getDecryptedBytes

public byte[] getDecryptedBytes()

getPrivateKey

public PrivateKey getPrivateKey()

getPublicKey

public PublicKey getPublicKey()
                       throws GeneralSecurityException
Throws:
GeneralSecurityException

opensslDecrypt

private static PKCS8Key.DecryptResult opensslDecrypt(PEMItem item,
                                                     char[] password)
                                              throws GeneralSecurityException
Throws:
GeneralSecurityException

generateCipher

public static Cipher generateCipher(String cipher,
                                    String mode,
                                    DerivedKey dk,
                                    boolean des2,
                                    byte[] iv,
                                    boolean decryptMode)
                             throws NoSuchAlgorithmException,
                                    NoSuchPaddingException,
                                    InvalidKeyException,
                                    InvalidAlgorithmParameterException
Throws:
NoSuchAlgorithmException
NoSuchPaddingException
InvalidKeyException
InvalidAlgorithmParameterException

decrypt

public static PKCS8Key.DecryptResult decrypt(String cipher,
                                             String mode,
                                             DerivedKey dk,
                                             boolean des2,
                                             byte[] iv,
                                             byte[] encryptedBytes)
                                      throws NoSuchAlgorithmException,
                                             NoSuchPaddingException,
                                             InvalidKeyException,
                                             InvalidAlgorithmParameterException,
                                             IllegalBlockSizeException,
                                             BadPaddingException
Throws:
NoSuchAlgorithmException
NoSuchPaddingException
InvalidKeyException
InvalidAlgorithmParameterException
IllegalBlockSizeException
BadPaddingException

decryptPKCS8

private static PKCS8Key.DecryptResult decryptPKCS8(ASN1Structure pkcs8,
                                                   char[] password)
                                            throws GeneralSecurityException
Throws:
GeneralSecurityException

deriveKeyV1

public static DerivedKey deriveKeyV1(byte[] password,
                                     byte[] salt,
                                     int iterations,
                                     int keySizeInBits,
                                     int ivSizeInBits,
                                     MessageDigest md)

deriveKeyPKCS12

public static DerivedKey deriveKeyPKCS12(char[] password,
                                         byte[] salt,
                                         int iterations,
                                         int keySizeInBits,
                                         int ivSizeInBits,
                                         MessageDigest md)

pkcs12

private static byte[] pkcs12(int idByte,
                             int n,
                             byte[] salt,
                             byte[] password,
                             int iterationCount,
                             MessageDigest md)
This PKCS12 key derivation code comes from BouncyCastle.

Parameters:
idByte - 1 == key, 2 == iv
n - keysize or ivsize
salt - 8 byte salt
password - password
iterationCount - iteration-count
md - The message digest to use
Returns:
byte[] the derived key

deriveKeyV2

public static DerivedKey deriveKeyV2(byte[] password,
                                     byte[] salt,
                                     int iterations,
                                     int keySizeInBits,
                                     int ivSizeInBits,
                                     Mac mac)
                              throws InvalidKeyException
Throws:
InvalidKeyException

formatAsPKCS8

public static byte[] formatAsPKCS8(byte[] privateKey,
                                   String oid,
                                   ASN1Structure pkcs8)

allZeroes

private static boolean allZeroes(byte[] b)

encode

public static byte[] encode(DEREncodable der)
                     throws IOException
Throws:
IOException

main

public static void main(String[] args)
                 throws Exception
Throws:
Exception