rails: Getting "ArgumentError: key must be 32 bytes" after upgrading to Ruby 2.4.0-preview1 with edge Rails

Steps to reproduce

  • Given you have a repo: https://github.com/jasnow/tasks5_edge
  • And you run “rake” (using Ruby 2.3.1), it runs without error
  • But when you upgrade the repo to use Ruby 2.4.0-preview1
  • And you run “rake”, you get this error message 3 times:
ArgumentError:
  key must be 32 bytes

Expected behavior

Expect the above test to run without the error message like it does with Ruby 2.3.1.

Actual behavior

Get error:

ArgumentError:
  key must be 32 bytes

The total stacktrace is here: https://gist.github.com/jasnow/4e0d394314eafd105a039c73a395c37f

System configuration

Rails version: Rails 5.1.0.alpha (revision: 0c998a14c45430afe85188f8ad13a696b077ffd9)

Ruby version: ruby-2.4.0-preview1

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 32 (8 by maintainers)

Commits related to this issue

Most upvoted comments

@AlexanderUlitin probably a bit late but leaving this here for reference, to decrypt previously encrypted data you can pass the old key (without truncate) as a second argument to ActiveSupport::MessageEncryptor. Example:

secret = ENV['SECRET_KEY'] # this represent a 64 chars key used on ruby 2.3

encryptor = ActiveSupport::MessageEncryptor.new(secret[0..31], secret)
encryptor.decrypt_and_verify(data)

For all those new to this, this is apparently not a bug: ext/openssl used to just truncate oversized keys up to a point: https://github.com/ruby/openssl/issues/116

@matthewd Thanks for pointing me in the right direction. In the lib/encryptor.rb file I had those lines :

passphrase = ActiveSupport::KeyGenerator.new(key).generate_key(salt)
@encryptor = ActiveSupport::MessageEncryptor.new(passphrase)

And everything was working fine until I updated to the last ruby version (2.4.0p0). To make it work, I added ‘32’ as argument to the ‘generate_key’ method. As follow :

passphrase = ActiveSupport::KeyGenerator.new(key).generate_key(salt,32)
@encryptor = ActiveSupport::MessageEncryptor.new(passphrase)

Maybe, it would help others.

@cnemeth The fix hasn’t been released yet (coming in 5.0.1 it looks like). You need to point your Gemfile at the 5-0-stable branch to get it now:

gem 'rails', github: 'rails/rails', branch: "5-0-stable"

EDIT: with all the caveats that you are technically using an edge/unreleased Rails version, don’t cut yourself etc etc etc

Why don’t you use : key = SecureRandom.random_bytes(32) crypt = ActiveSupport::MessageEncryptor.new(key) encrypted_data = crypt.encrypt_and_sign(‘my secret random data’) crypt.decrypt_and_verify(encrypted_data) => “my secret random data”

FWIW I found this error resolved by using 5.0.2

Still getting error when I go from 2.3.1 to 2.4.0-preview1 on above repo.

@devohh yes, that works for me too, but for new generated data, but if I have previously encrypted data - I can’t decrypt it after this fix.

Anyone have any idea how to decrypt the string, that was created with 64 chars key (when I used ruby 2.3)?

I’m on Ruby 2.4.0 and Rails 5.0.2 and I’m still getting this error.

Here’s my code:

ENCRYPTION_KEY_GENERATOR = ActiveSupport::KeyGenerator.new(ENV['X'])
ENCRYPTION_KEY = ENCRYPTION_KEY_GENERATOR.generate_key(ENV['Y'])
ENCRYPTOR = ActiveSupport::MessageEncryptor.new(ENCRYPTION_KEY)

I’m definitely on Rails 5.0.2:

> Rails::VERSION::STRING
=> "5.0.2"

Here’s me reproducing it:

> ENCRYPTOR.encrypt_and_sign('a')
ArgumentError: key must be 32 bytes
from /usr/local/bundle/gems/activesupport-5.0.2/lib/active_support/message_encryptor.rb:79:in `key='

Getting this error with Rails 5.0.0.1 and ruby 2.4.0p0.

Error resolves with @nateberkopec’s solution.

I’m still having this issue after upgrading from ruby 2.3.1 to 2.4.0-preview2

ruby 2.4.0preview2 (2016-09-09 trunk 56129) [x86_64-darwin15] Rails 5.0.0.1

stack trace https://gist.github.com/cnemeth/42ae67172ebe45417473172a3a6382fc

I’m getting this error under Ruby 2.4.0p0 and Rails 4.2.7.1. Is Rails 4.2 going to get this fix?

Still having this issue with Ruby 2.6.1 and Rails 5.2.4.1

Same problem here, but i’m using ruby 2.6.3 and Rails 5.1.6

It was the same for me. Did you try ? Just adding 32 as parameter to the generate_key method. It worked for me.

ENCRYPTION_KEY = ENCRYPTION_KEY_GENERATOR.generate_key(ENV['Y'], 32)

this error resolved by using 5.0.2

@miltzi the same issue I had, but upgrade of fails (5.0.0.1 -> 5.0.1) helped.

This is being fixed in https://github.com/rails/rails/pull/25192. Closing this issue as there is already PR and discussion around it.