4
votes

I've created an RSA private key in ruby with:

require 'openssl'
key = OpenSSL::PKey::RSA.generate(1024)

I can get the key in PEM or DER formats:

key.to_pem
key.to_der

But there doesn't seem to be a way to get it into PKCS#8 format. The best I've come up with is to call out to openssl in another process:

require 'open3'
Open3.popen3('openssl pkcs8 -topk8 -inform PEM -outform PEM -passout pass:password') do |stdin,  stdout, stderr|
  stdin.write(key.to_pem)
  unless (err = stderr.read).empty? then raise err end
  stdout.read
end

There must be a better way that I just can't find. Does the OpenSSL class library in ruby have a mechanism for doing this?

2

2 Answers

2
votes

I think I found a way to do this by hacking on a new method to the OpenSSL::PKey::RSA class that outputs in PKCS#8 format. It's rather ugly and could use some cleaning up, but manages to create valid records:

key = OpenSSL::PKey::RSA.new(1024)

key.to_pem_pkcs8
# => "-----BEGIN PRIVATE KEY----- ..."

This method works like the usual to_pem but makes a call to a different OpenSSL exporter method.

1
votes

There is support in Ruby trunk for exporting private keys to PKCS#8 format, using the new private_to_pem and private_to_der methods on OpenSSL::PKey::PKey (and subclasses). So Real Soon Now, or Right Now if you like living on the bleeding edge, we'll finally be able to write out PKCS#8 keys natively.