Tuesday, June 29, 2010

Ruby and OpenSSL with SSH keys

One of the challenges of dealing with encryption is the management of keys. We have a SSH key, a PGP key (probably multiple), maybe a OpenSSL cert, perhaps another cert somewhere for S/MIME and maybe a ton more for various other purposes. This post is basically an addendum to my last File Encryption in Ruby with OpenSSL, but I will step through the code using an SSH key instead. This will minimize the amount of keys you have to manage and it will utilize a key that many people have readily available to them without the need to create yet another encryption key.

SSH Keys

On the chance that you do not have an ssh key (you really should you know) or you are using DSA keys you will need to create an RSA key with ssh-keygen.

home$ ssh-keygen -t rsa -b 2048 -N 'mypass'

Loading the SSH key in Ruby

Loading the SSH/RSA key is relatively straight forward. Instead of pointing to our generated RSA key from the last posting we will simply point it to the path of our SSH/RSA key and load it with the password we supplied during the ssh-keygen step. I will demonstrate in an irb session.

# Require the OpenSSL library
irb> require 'openssl'
# Load the SSH key from the default location (Linux/UNIX)
irb> key = OpenSSL::PKey::RSA.new(File.read("#{ENV['HOME']}/.ssh/id_rsa"),'mypass')

The generated public SSH/RSA key is not stored in PEM format so you cannot consume it with OpenSSL, but you can generate it from the private key and store it alongside the SSH formatted one.

# Write the PEM encoded public key alongside the SSH public key
irb> File.open("#{ENV['HOME']}/.ssh/id_rsa.pub.pem") do |f|
irb>     f.write(key.public_key.to_pem)
irb> end

So there you go. You can now load your SSH key for encryption/decryption purposes with the OpenSSL library and you won't have to worry about managing keys. All else remains the same and you can do everything that was done in my previous OpenSSL/Ruby posting.