web-dev-qa-db-ja.com

Rails 5 cipher.key "key must be 32 bytes"エラー

真新しいRailsアプリケーション。

Railsバージョン5.0.0.1、Rubyバージョン2.4.0preview2。

アプリケーション「デモ」を作成し、単純なスキャフォールド生成製品を実行して、スキャフォールドの概要ページを表示しようとするとエラーが発生します(ベースインデックスファイルはまだWelcome to Rails screen fine)をロードします):

ProductsController#indexキーのArgumentErrorは32バイトでなければなりません:

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

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

問題の行は明らかにcipher.key = @secretです。

私はgithubリポジトリでRailsについてこの問題について言及しているさまざまな言及を見てきましたが、Rails 5.0.0.1

14

わかりました。少し誤解がありました。5.0.0.1ではなく5.0.1で修正が行われているようです。

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

6

最後に問題が見つかりました!これはバグ修正によるものです... 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文字のnonceを送信する必要があると思っていましたが、実際には32文字のnonceを送信するか、cipher.random_key(内部でkey_lenを使用)を使用することになっています。 opensslがnonceを切り捨てたため、以前は問題になりませんでしたが、正しい長さのnonceを送信する必要があります。

Ruby 2.3.4から2.4.2にアップグレードするときにこのエラーが発生しました。

2
xxjjnn

これを試して:

rake db:create
rake db:migrate

次に、最も重要なこと:

bundle update

これは私にとってはうまくいきます。

1
Naomi Wu

ソリューション

  1. Gemfileを編集する
  2. 次の行を追加します:gem 'Rails'、 '〜> 5.0.0'、 '> = 5.0.0.1'
  3. バンドルインストール
  4. オプション:Ruby2-4.1を使用しています。 (rvm install Ruby-2.4.1)

Rational:Rails 5.0.0より前のバージョンには、この問題の原因となるバグがあるようです。バグはRailsの最新バージョンで解決されました。Railsインストールガイド( http://railsapps.github.io/installrubyonrails-mac.html )に従っている場合この投稿日現在、おそらくこの問題が発生します。

この修正は機能し、以下によって検証されます

1
FlyingV

使用する random_keyしたがって、常に適合します。

key = cipher.random_key
cipher.key = key

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

1
Bater

この問題は、使用しているキーに関連していることが判明しました。キーを変更せずに、以下のコードを使用してキーを32バイトに変換できます。

attr_encrypted:属性、キー:ENV ['MY_KEY']。bytes [0..31] .pack( "c" * 32)

1
Chris

私もこの問題を抱えていて、実行して修正しました

bundle update

Railsの最新バージョンがインストールされていることを確認してください。

1
DVislearning

同じエラーが発生しました:バンドル更新を実行するとうまくいくはずです

0
Ahmed J.

32バイトを取得するにはDigest :: MD5を使用してください

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
0
Govind shaw