LoginSignup
8
5

More than 3 years have passed since last update.

【Ruby 2.4.6 update】ArgumentError: key must be 32 bytes への、versionを動かさない対処

Last updated at Posted at 2019-07-24

背景

Ruby 2.3.1 -> 2.4.6 へversion upしたら、ActiveSupport::MessageEncryptor周りでエラーがでた。
この中で使われているOpenSSLがもともと32bytes以上でも受け入れていたところを、32バイトぴったりしか受け付けなくなったのが原因の様子。
これが修正のcommit
データベースに32バイトより大きいkeyで暗号化したデータが入っていたので、それらをdecryptできなくて落ちていた。
ちなみにRailsは4系。

捕捉

Rails 5.0.0.1 で対応が入っているらしい
https://github.com/rails/rails/pull/25192/files
でも今回はRailsのversionは上げられないので別の対処法を探す。
色々調べた感じ、多くの人はRubyのversionを戻したりとversionを上げ下げしてこの問題を回避してそうだった。

解決案その1

Ruby 2.3系に戻し、32バイトより大きいkeyでdecryptして、32bytesでまたencryptする。
これでもいいのですが、ちょっと時間がかかりそう。

参考

解決案その2

32バイトっていうので、とりあえず32bytesにしてみた。
しかしdecryptで失敗。
これはchiperの方はsecretを32bytesに切ってくれるが、復号で使うverifierの方はそのままの長さを使ってるからのが原因の模様。

d = ActiveSupport::MessageEncryptor.new(some_key[0..31])
rb(main):005:0> d.encrypt_and_sign("hoge")
=> "K3dtYVJUL1NucVpnRUFJWm9OZ3VQQT09LS1SMlRKb3dWWXFFajZ5MDFMcHQ3NmxRPT0=--910efa18ef525a38f7bf2482e94a54ec39ad1e65"

d = ActiveSupport::MessageEncryptor.new(some_key[0..31])
irb(main):003:0> d.encrypt_and_sign("hoge")
ArgumentError: key must be 32 bytes

しかし、ActiveSupport::MessageEncryptorのコードを読んでいたら、optionsで渡せそう。
option引数の先頭で渡せば@sign_secretに入って、そっちが優先されてverifierが作成される。

#=>  ActiveSupport::MessageEncryptor
    def initialize(secret, *signature_key_or_options)
      options = signature_key_or_options.extract_options!
      sign_secret = signature_key_or_options.first
      @secret = secret
      @sign_secret = sign_secret
      @cipher = options[:cipher] || 'aes-256-cbc'
      @verifier = MessageVerifier.new(@sign_secret || @secret, digest: options[:digest] || 'SHA1', serializer: NullSerializer)
      @serializer = options[:serializer] || Marshal
    end

つまりこうすれば良い。

  ActiveSupport::MessageEncryptor.new(some_key[0..31], some_key) 

急ぎだったので、解決案2で解決しました。
salt使うように修正予定。

終わり

ベテランの方に助けてもらいました
ライブラリのコードリーディング力を高めなければ

8
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5