バグ #842
完了OpenSSL::Cipher#key= に長すぎるキーを指定しないようにする
説明
以前は OpenSSL::Cipher#key= に長すぎる文字列を渡した場合、勝手に(bf-ecb なら)16 バイトに切り詰められていたのですが、RDoc にも言及がなくどう考えても不自然な挙動なので、2 日前に r55146 (https://github.com/ruby/ruby/commit/ce635262f53b760284d56bb1027baebaaec175d1) で弾かれるように変更しました。
mikutter では SecureRandom.hex(= 32 バイト)を直接渡しているため、この影響を受けてしまっています。これは mikutter 側で修正するべきだと思うのですがどうでしょうか。
diff --git a/core/service_keeper.rb b/core/service_keeper.rb index cdf18fa..fc4775e 100644 --- a/core/service_keeper.rb +++ b/core/service_keeper.rb @@ -15,7 +15,8 @@ class Service @@service_lock = Monitor.new def key - UserConfig[:account_crypt_key] ||= SecureRandom.hex end + key = UserConfig[:account_crypt_key] ||= SecureRandom.hex(8) + key[0, 16] end # 全てのアカウント情報をオブジェクトとして返す # ==== Return
再現手順
rubyのHEADでmikutterを起動する
関連するチケット
toshi_a 初音 さんが8年以上前に更新
- 担当者 を toshi_a 初音 から rhen ium に変更
丁度2倍になっているところから、SecureRandom.hexの戻り値が16進表記なのを失念していて、倍のサイズを渡したのだろうと推察できますね。
- SecureRandom.hexだと16進数の文字列しか得られないため、キーのパターンが半分になってしまう
- キーのサイズを指定すると、今回指摘されたようなミスが発生してしまうのではないか
と思って解決策を探っていたところ、 OpenSSL::Cipher#random_key を使ったほうが良いのではないかと思いました。釈迦に説法だと思うので詳しくは割愛しますが、どう思いますか?
rhen ium さんが8年以上前に更新
- 担当者 を rhen ium から toshi_a 初音 に変更
ここでは UserConfig から読み込んだキーで復号したいので OpenSSL::Cipher#random_key は使えないと思います。
SecureRandom.random_bytes(16) で 16 バイトのランダムな文字列が得られますが、YAML ってバイナリデータ大丈夫なんでしたっけ…
bf-ecb のキー長は可変なので、適当な定数を置いて
KEY_LEN = 16 def key key = UserConfig[:account_crypt_key] ||= SecureRandom.random_bytes(KEY_LEN) key[0, KEY_LEN] end def encrypt(str) cipher = OpenSSL::Cipher.new('bf-ecb').encrypt cipher.key_len = KEY_LEN cipher.key = key cipher.update(str) << cipher.final end
のようにするのが良さそうです。
toshi_a 初音 さんが8年以上前に更新
- ステータス を 新規 から レビュー待ち に変更
- 担当者 を toshi_a 初音 から rhen ium に変更
- 再現手順 を更新 (差分)
薄い本…OSC…とだらだらしていたらえらく引っ張ってしまいました。
ブランチ topic/842-too-long-cipher-key に、貰ったアドバイスを参考にした変更を入れました。確認してみてください。
YAMLはバイナリデータ突っ込んでもBASE64か何かでエンコードしてよしなに扱うことができたような …と思って試したら、Rubyでも問題なかったので利用しました。まあそれも含めて結局提案してもらったとおりですね。