Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ruby open ssl api for encrypted key (without nodes option)

On a linux machine with openssl lib installed, when you perform “openssl pkcs12” with “-nodes” option then you get output with unencrypted private key but if you skip the –nodes option then output will have encrypted private key.

     e.g.
             openssl pkcs12 -in test.pfx -out test.pem 

You should see private key encrypted like below

-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFDjBABgkqhkiGG7s=
-----END ENCRYPTED PRIVATE KEY-----

How do I achive the above using ruby's open ssl library?

This is how I am generating the private key with ruby:

    @private_key = OpenSSL::PKey::RSA.new 2048
    @private_key.to_pem.to_s

EDIT:

I guess my question how does this command encrypt the private key:

openssl pkcs12 -in test.pfx -out test.pem

whereas:

“openssl pkcs12 -nodes -in test.pfx -out test.pem"

does not. How do i get the same results using ruby?

like image 788
Micheal Avatar asked Jan 09 '18 22:01

Micheal


1 Answers

There must be something more to this. Perhaps the question needs refined. From what I can tell, you want to print a private key in PEM format. I'm not a ruby programmer but I got this working in about 3 minutes by reading the on ruby-docs.org:

$ cat ssl.rb 
require 'openssl'
key = OpenSSL::PKey::RSA.new 2048
cipher = OpenSSL::Cipher.new 'AES-128-CBC'
pass_phrase = 'my secure pass phrase goes here'
key_secure = key.export cipher, pass_phrase
puts key_secure

Choose your cipher and your passphrase and voila, you have encrypted a key with a symmetric cipher:

$ ruby ssl.rb
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,D8062F93C8854E593602D503E1FAC309

UsNQt/Bq7QBldOBU7NW6miCDuC+ODpeplaWQ9BvJW4Wg7j0AbKgMZAn7juegAbjG
JVkpdDNzhs37UVWmqwg64yYP6KEBGg4zCog2a993UHRvFTQb6tyugKHc+uFeyY+D
...
-----END RSA PRIVATE KEY-----

Is there something more you're trying to do?

--

EDIT: The Asker has clarified that the question is about which encryption is used by openssl pkcs12 when not using the -nodes option.

The -nodes option turns off DES encryption. This page shows that the default encryption for private key creation is triple DES, but I don't see the detail there about which DES option. This is also referred to in the manual for man pkcs12. In any case, it's not yet clear to me if you need to know exactly which cipher is used by openssl or if your question is now answered.

You can list ruby's available ciphers like this:

puts OpenSSL::Cipher.cipher 

(as specified in the docs)

On my system, quite a few DES ciphers are available with varying parameters:

des
des-cbc
des-cfb
des-cfb1
des-cfb8
des-ecb
des-ede
des-ede-cbc
des-ede-cfb
des-ede-ofb
des-ede3
des-ede3-cbc
des-ede3-cfb
des-ede3-cfb1
des-ede3-cfb8
des-ede3-ofb
des-ofb
des3
desx
desx-cbc

I'm not sure if the PKCS12 spec says which DES cipher should be used or if openssl just has a default. Are you trying to figure out which DES cipher is used by OpenSSL?

I looked a bit further through the openssl wiki and I found references to DES in CBC mode, so I'm guessing that the cipher you are looking for is DES-EDE3-CBC.

Sorry, I guess it's still not completely clear exactly what question you're trying to answer. If what you're trying to do is to find out exactly how openssl is encoding the private key when you don't use -nodes you can see that by cating the file into openssl asn1parse. Maybe this helps: you can start with your rsa private key in plain text as you got it from your ruby program:

$ cat key.pem
-----BEGIN RSA PRIVATE KEY-----
MIIEpA....
-----END RSA PRIVATE KEY
$ cat key.pem | openssl asn1parse
    0:d=0  hl=4 l=1188 cons: SEQUENCE          
4:d=1  hl=2 l=   1 prim: INTEGER           :00
7:d=1  hl=4 l= 257 prim: INTEGER       ...

You'll see that this is encoded as an ASN1 SEQUENCE of long integers.

But if you put your key through a roundtrip of pkcs12:

$ openssl pkcs12 -inkey key.pem -out key.pfx -export -nocerts -nodes
(choose a password)
$ openssl pkcs12 -in key.pfx -out outkey.pem -nodes
(enter password)

You'll find your key now wrapped in a new structure, which you can cat to asn1parse:

cat keyout.pem | openssl asn1parse
    0:d=0  hl=4 l=1214 cons: SEQUENCE          
    4:d=1  hl=2 l=   1 prim: INTEGER           :00
    7:d=1  hl=2 l=  13 cons: SEQUENCE          
    9:d=2  hl=2 l=   9 prim: OBJECT            :rsaEncryption

You now have an ASN1 rsaEncryption Object with a payload of a large octet string.

Is this what you were trying to learn about? How these values are encapsulated in ASN1?

like image 129
JawguyChooser Avatar answered Oct 10 '22 07:10

JawguyChooser