Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Load PKCS#8 binary key into Ruby

I'm trying to load a particular private key encoded in binary DER format (PKCS#8) into Ruby.

However, OpenSSL::PKey won't recognize it. I can make it work by doing some console work and transforming it into a PEM like so:

openssl pkcs8 -inform DER -in file.key -passin pass:xxxxxxxx >private_key.pem

After this, the key can correctly be read.

However, since I would like for the whole process to be done in memory instead of writing and reading files.

So my question is: Is it possible to load private keys from the binary encoded DER format into Ruby/OpenSSL?

Thank you for your time,

Fernando

like image 581
Fernando Gonzalez Avatar asked Jan 20 '11 22:01

Fernando Gonzalez


1 Answers

Yes, you can indirectly load PKCS#8 DER-encoded private keys using Ruby OpenSSL.

OpenSSL::PKey::RSA.new will only handle PEM-formatted PKCS#8, but it is easy to read the binary DER and convert it to a PEM-formatted string and then load from the string.

For example, with these DER-encoded private keys:

$ openssl genrsa | openssl pkcs8 -topk8 -outform DER \
    -nocrypt -out pkcs8.key
$ openssl genrsa | openssl pkcs8 -topk8 -outform DER \
    -v2 des3 -passout pass:secret -out pkcs8_des3.key

You can do something like this:

require 'openssl'
require 'base64'

def box(tag, lines)
  lines.unshift "-----BEGIN #{tag}-----"
  lines.push "-----END #{tag}-----"
  lines.join("\n")
end

def der_to_pem(tag, der)
  box tag, Base64.strict_encode64(der).scan(/.{1,64}/)
end

pem = der_to_pem('PRIVATE KEY', File.read('pkcs8.key'))
key = OpenSSL::PKey::RSA.new(pem)

pem2 = der_to_pem('ENCRYPTED PRIVATE KEY', File.read('pkcs8_des3.key'))
key2 = OpenSSL::PKey::RSA.new(pem2, 'secret')

Read the DER bytes, Base64 them and put the PEM tags on top and bottom, and then load the key.

like image 90
Jim Flood Avatar answered Nov 12 '22 08:11

Jim Flood