真新しい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
わかりました。少し誤解がありました。5.0.0.1ではなく5.0.1で修正が行われているようです。
最後に問題が見つかりました!これはバグ修正によるものです... 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にアップグレードするときにこのエラーが発生しました。
これを試して:
rake db:create
rake db:migrate
次に、最も重要なこと:
bundle update
これは私にとってはうまくいきます。
ソリューション:
Rational:Rails 5.0.0より前のバージョンには、この問題の原因となるバグがあるようです。バグはRailsの最新バージョンで解決されました。Railsインストールガイド( http://railsapps.github.io/installrubyonrails-mac.html )に従っている場合この投稿日現在、おそらくこの問題が発生します。
この修正は機能し、以下によって検証されます
使用する random_key
したがって、常に適合します。
key = cipher.random_key
cipher.key = key
参照 http://Ruby-doc.org/stdlib-2.0.0/libdoc/openssl/rdoc/OpenSSL/Cipher.html
この問題は、使用しているキーに関連していることが判明しました。キーを変更せずに、以下のコードを使用してキーを32バイトに変換できます。
attr_encrypted:属性、キー:ENV ['MY_KEY']。bytes [0..31] .pack( "c" * 32)
私もこの問題を抱えていて、実行して修正しました
bundle update
Railsの最新バージョンがインストールされていることを確認してください。
同じエラーが発生しました:バンドル更新を実行するとうまくいくはずです
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