There are quite a few pieces that go into implementing a Java key store that we had to roll ourselves
Keystores::Jks::EncryptedPrivateKeyInfo
PKCS#8 defines the following syntax for an encrypted private key:
EncryptedPrivateKeyInfo ::= SEQUENCE {
encryptionAlgorithm AlgorithmIdentifier,
encryptedData OCTET STRING }
Java's implementation actually encodes the following:
EncryptedPrivateKeyInfo ::= SEQUENCE {
SEQUENCE {
null,
encryptionAlgorithm AlgorithmIdentifier},
encryptedData OCTET STRING }
For some reason, they wrap the PKCS8 sequence in another sequence, and throw a null in there for good measure.
This class is pretty much a direct port of sun.security.provider.KeyProtector
.
It implements a proprietary PBE of sorts.
TODO, I would like to implement this as a proper OpenSSL::Cipher
object.
This file cracks open the OpenSSL::PKey
classes and enables them to both parse and encode keys
in PKCS#8 format. This is implemented for EC
, RSA
, and DSA
keys.
Parsing is implemented as replacing the original initialize
method with one that converts the DER
encoded key to PEM, and then calls the original initialize
method. This is because for some reason,
the built in OpenSSL::PKey
object constructors can parse a PEM encoded PKCS8 key just fine, but it
blows up on a DER encoded key.
This provides a method OpenSSL::PKey.pkcs8_parse
that parses the ASN.1 encoded key structure, extracts
the key type, and returns the correct OpenSSL::PKey
object.
This provides a method OpenSSL::PKey::{RSA,DSA,EC}.to_pkcs8
that encodes each key type into its correct
PKCS#8 format. The Ruby OpenSSL wrapper doesn't give you access to PKCS8 capabilities in OpenSSL, and even if
it did, not all versions of openssl that are packaged with ruby implement PKCS8 encoding.