Rails 5 cipher.key“key必须是32个字节”错误

时间:2016-09-28 07:59:52

标签: ruby-on-rails ruby ruby-on-rails-5

全新的Rails应用程序。

Rails版本5.0.0.1,Ruby版本2.4.0preview2。

创建应用程序“demo”,运行一个简单的脚手架生成Product,并在尝试查看脚手架的概述页面时出错(基本索引文件仍然可以加载Welcome to Rails屏幕):

ProductsController #index中的ArgumentError key必须是32个字节:

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

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

问题行显然是cipher.key = @secret。

我已经看到Rails提到这个问题的github repo上的各种提及,但是所有这些都暗示它现在已经在Rails 5.0.0.1中解决了

9 个答案:

答案 0 :(得分:3)

好的,我有一点误会,看起来修复程序在5.0.1而不是5.0.0.1

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

答案 1 :(得分:2)

试试这个:

rake db:create
rake db:migrate

然后,最重要的是:

bundle update

这对我有用。

答案 2 :(得分:2)

终于找到了问题!它来自一个错误修正... https://bugs.ruby-lang.org/issues/12561

如果您使用密码,例如' aes-256-cfb',key_len为32,发现者:

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

我们错误地认为我们需要发送一个256个字符的随机数,但实际上你应该发送一个32个字符的随机数 - 或者  使用cipher.random_key(内部使用key_len)。它从来都不是一个问题,因为openssl截断了nonce ...但现在你需要发送正确的长度nonce。

我们在将ruby从2.3.4升级到2.4.2时遇到此错误。

答案 3 :(得分:1)

使用random_key以便它始终适合。

key = cipher.random_key
cipher.key = key

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

答案 4 :(得分:1)

解决方案

  1. 编辑您的Gemfile
  2. 添加以下行:gem' rails','〜> 5.0.0','> = 5.0.0.1'
  3. 捆绑安装
  4. 可选:我使用的是ruby2-4.1。 (rvm install ruby​​-2.4.1)
  5. Rational :5.0.0之前的rails版本似乎有一个导致此问题的错误。该错误已在最新版本的Rails中得到解决。如果您正在遵循Rails安装指南(http://railsapps.github.io/installrubyonrails-mac.html),则可能会在此过帐日期遇到此问题。

    此修复程序确实有效,并由

    验证

答案 5 :(得分:1)

我也遇到了这个问题并通过运行

修复了它
bundle update

确保安装了最新版本的rails。

答案 6 :(得分:0)

有同样的错误: 运行捆绑包更新应该可以解决问题

答案 7 :(得分:0)

请使用 Digest :: MD5 达到32个字节

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",""

或者只需使用长度为32个字节的秘密密钥

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

答案 8 :(得分:0)

事实证明此问题与您使用的钥匙有关。无需更改密钥,您可以使用下面的代码将密钥转换为32个字节:

  

attr_encrypted:属性,密钥:ENV ['MY_KEY']。bytes [0..31] .pack(“ c” * 32)