TheMinimalCriminal
TheMinimalCriminal

Reputation: 503

Rails 5 cipher.key "key must be 32 bytes" error

Brand new Rails application.

Rails version 5.0.0.1, Ruby version 2.4.0preview2.

Create application "demo", run a simple scaffold generate Product, and get an error when trying to view the scaffold's overview page (base index file still loads the Welcome to Rails screen fine):

ArgumentError in ProductsController#index key must be 32 bytes:

  cipher = new_cipher
  cipher.encrypt
  cipher.key = @secret

  # Rely on OpenSSL for the initialization vector
  iv = cipher.random_iv

The problem line is apparently cipher.key = @secret.

I've seen various mentions on the github repo for Rails mentioning this issue, but all implied it was now resolved in Rails 5.0.0.1

Upvotes: 20

Views: 23672

Answers (9)

Chris
Chris

Reputation: 368

This issue turns out to be connected to the key you are using. Without changing your key you can use the code below to transform your key to 32 bytes:

attr_encrypted :attribute, key: ENV['MY_KEY'].bytes[0..31].pack( "c" * 32 )

Upvotes: 2

Govind shaw
Govind shaw

Reputation: 427

Please use Digest::MD5 to achive 32 bytes

require 'openssl'
require 'digest'
require 'base64'

data = "encrypt me"
secret_key = "asd3dssdf34HDas"
c = OpenSSL::Cipher.new("aes-256-cbc")
c.encrypt
c.key = Digest::MD5.hexdigest(secret_key) # this will convert key length into 32
encrypted_data = c.update(data.to_s) + c.final
encrypted_data = Base64.urlsafe_encode64(encrypted_data, padding: false) #padding: false will remove '/', '+' from encrypted data
encrypted_data.gsub! "\n",""

Or Simply use secret key of length 32 bytes

data = "encrypt me"
secret_key = "Aswertyuioasdfghjkqwertyuiqwerty"
c = OpenSSL::Cipher.new("aes-256-cbc")
c.encrypt
c.key = secret_key 
encrypted_data = c.update(data.to_s) + c.final

Upvotes: 4

Ahmed J.
Ahmed J.

Reputation: 522

Had the same error: Running bundle update should do the trick

Upvotes: 0

DVislearning
DVislearning

Reputation: 21

I was having this problem too and fixed it by running

bundle update

Make sure that you have the latest version of rails installed.

Upvotes: 1

FlyingV
FlyingV

Reputation: 3535

Solution:

  1. Edit your Gemfile
  2. Add the following line: gem 'rails', '~> 5.0.0', '>= 5.0.0.1'
  3. bundle install
  4. Optional: I am using ruby2-4.1 . (rvm install ruby-2.4.1)

Rational: The rails version prior to 5.0.0 seems to have a bug that causes this issue. The bug has been resolved in the latest version of Rails. If you hare following the Rails Installation Guide (http://railsapps.github.io/installrubyonrails-mac.html) you will probably encounter this problem as of this posting date.

This fix does work, and is verified by

Upvotes: 1

xxjjnn
xxjjnn

Reputation: 15239

Finally found problem! It was from a bugfix... https://bugs.ruby-lang.org/issues/12561

If you are using cipher e.g. 'aes-256-cfb', the key_len is 32, found by:

require 'openssl'
cipher = OpenSSL::Cipher.new('aes-256-cfb')
cipher.key_len # => 32

We had mistakenly thought we needed to send a 256 character nonce, but actually you are supposed to send a 32 character nonce - or use cipher.random_key (which internally uses the key_len). It never used to be a problem because openssl truncated the nonce... but now you need to send the right lengthed nonce.

We got this error upgrading ruby from 2.3.4 to 2.4.2.

Upvotes: 2

Bater
Bater

Reputation: 61

Use random_key so it always fit.

key = cipher.random_key
cipher.key = key

reference http://ruby-doc.org/stdlib-2.0.0/libdoc/openssl/rdoc/OpenSSL/Cipher.html

Upvotes: 1

Naomi Wu
Naomi Wu

Reputation: 29

try this:

rake db:create
rake db:migrate

then, the most important thing:

bundle update

This works for me.

Upvotes: 1

TheMinimalCriminal
TheMinimalCriminal

Reputation: 503

Ok, there was a slight misunderstanding on my part, looks like the fix is coming in 5.0.1 not 5.0.0.1

https://github.com/rails/rails/issues/26694

Upvotes: 11

Related Questions