Ruby
Rails
Rails4.2
Ruby2.4

rails 4.2.10とruby 2.4.3 で `key must be 32 bytes`の例外が発生する

現象

railsとrubyのバージョンをあげたところkey must be 32 bytesの例外が発生するようになりました。

例外は、暗号化に利用していたActiveSupport::MessageEncryptorから発生していました。

どうやら、rubyのopenssl周りで変更があり、暗号化キーには正しく32byteのキーを渡すことが必要になったようです(aes-256-cbc方式を利用する場合)。
+ https://qiita.com/KTakata/items/7bc8057b3b0ca6759b12
+ https://github.com/rails/rails/issues/25185

また、これまで、32byte以上のキーを渡して場合はキーの32byte以降のデータが利用されないようになっていたようです。
+ https://gist.github.com/rhenium/b81355fe816dcfae459cc5eadfc4f6f9

対応

もし、暗号化キーを文字列で渡しているのであれば、以下のようにすることで問題を回避できるようです。

secret = "0123456789abcdef" * 8
encryptor = ActiveSupport::MessageEncryptor.new(secret[0..31], "salt-salt-salt")
# 暗号化処理
encrypt_data = encryptor.encrypt_and_sign(private_data)
# 復号処理
decrypt_data = encryptor.decrypt_and_verify(encrypt_data)

:construction: 注意

この対応のセキュリティー的な正しさについては、分からない部分があるので参考にとどめてください。

参考