Ryan Grush
Ryan Grush

Reputation: 2128

OpenSSL key length too short in Ruby, not in Bash

I originally experimented with a simple encryption script in Bash and it worked pretty much as expected. However, I'm now trying to do the same thing in Ruby and the Ruby version seems function a little differently.

Bash

Encrypt

echo 'hello' | openssl enc -aes-256-cbc -a

Password: mypass

Result: U2FsdGVkX19rERfOXiKs97FgwIkLy3+ttZzaHkEoQyE=

Decrypt

echo 'U2FsdGVkX19rERfOXiKs97FgwIkLy3+ttZzaHkEoQyE=' | openssl aes-256-cbc -d -a

Password: mypass

Result: hello


Ruby

require "openssl"
require 'base64'

cipher = OpenSSL::Cipher.new('AES-256-CBC').encrypt
cipher.key = 'mypass'

This is what I've attempted in Ruby so far but I receive a OpenSSL::Cipher::CipherError: key length too short error. I would like to mimic Bash as much as possible.

Upvotes: 3

Views: 2085

Answers (1)

Maarten Bodewes
Maarten Bodewes

Reputation: 93968

OpenSSL uses a (largely undocumented) password based key derivation function (PBKDF) called EVP_BytesToKey using an 8 byte salt and an iteration count of 1. A magic and salt of 8 bytes each are prefixed to the ciphertext (check the first bytes of the result to see the magic).

Obviously "mypass" cannot be a correct key for AES. AES keys are 16, 24 or 32 byte binary values for the 128, 192 and 256 key sizes. You can however specify a key directly using the -K switch on the command line to make the code compatible with the Ruby Cipher object. In that case you need to specify the key using binary (a file) or hexadecimals for the openssl command line and in Ruby. You would also need to specify an IV.

Alternatively you would have to find an EVP_BytesToKey implementation for Ruby, but note that this is an old OpenSSL specific function with a completely insecure iteration count.

Upvotes: 5

Related Questions