blog.kotamiyake.me

為せば成る、為さねば成らぬ何事も

以前MessageEncryptorを使った暗号化を紹介したのですが、Rails 5.2では若干使い方が変わっていたので紹介します。

ドキュメントに従い、以下のように書き直します。

pry(main)> len = ActiveSupport::MessageEncryptor.key_len
=> 32
pry(main)> salt = SecureRandom.random_bytes(len)
=> "\x10\x8D\xCC\x19%\xD0\x9F{_\xB9\x9C\xDF\xEC\xE9\x10\xA3\xF9\x82\"\r\xE1\xAF\x01.\x17\x00\xAD\xA3=\xA6\xD2\x00"
pry(main)> key = ActiveSupport::KeyGenerator.new('salary').generate_key(salt, len)
=> "\"<\xE7\xC7-Z\xB6\xEA\xB29\x8B\xEBY\x9E\xEF!2\xFCL\x98\x02\xC7\x98;p'@6\xE0gV\xE9"
pry(main)> crypt = ActiveSupport::MessageEncryptor.new(key)
=> #<ActiveSupport::MessageEncryptor:0x00007fe0bd1540f0
 @aead_mode=true,
 @cipher="aes-256-gcm",
 @options={},
 @rotations=[],
 @secret="\"<\xE7\xC7-Z\xB6\xEA\xB29\x8B\xEBY\x9E\xEF!2\xFCL\x98\x02\xC7\x98;p'@6\xE0gV\xE9",
 @serializer=Marshal,
 @sign_secret=nil,
 @verifier=ActiveSupport::MessageEncryptor::NullVerifier>
pry(main)> encrypted_data = crypt.encrypt_and_sign(10000)
=> "vIhnJ/+b--dVcRCewozcXpKK8c--4UyU9gWcUa46EdjtLBx3vQ=="
pry(main)> crypt.decrypt_and_verify(encrypted_data) 
=> 10000

なぜ使い方が変わったのかと言うと、

これまではkeyに長過ぎる値を渡した場合は勝手に正しい長さに切り取ってくれたが、「想定外の結果(unexpected encryption/decryption results)」を引き起こすとして、正しい長さのkeyを渡さないと例外がraiseされるようになった。

ActiveSupport::MessageEncryptorを慎重に使う – nisshieeのブログ – https://nisshiee.hatenablog.jp/entry/2017/04/17/192703

ということらしい。

そのため以前のコードを実行するとエラーになります。

pry(main)> salery = 10000
=> 10000
pry(main)> secret = SecureRandom.hex(128)
=> "b991b09ab1a52e6649e5f836c4efcb28ec0d7e899e88be7b072cf752bf2194e8d2600dc524748f67d400a831f967a3a7b7c0b64d0af7b19cc2ee92300aa8c028699ca35ed9bb28f45d6238bf37476832e89638c200efb9ef8dccdf368f920d9d4a6ad941402a6c0ebb078e5b80d2ce76e3dafe45c3d44389c9c3633e710afde2"
pry(main)> encryptor = ::ActiveSupport::MessageEncryptor.new(secret)
=> #<ActiveSupport::MessageEncryptor:0x00007fe0c1bd3f68
 @aead_mode=true,
 @cipher="aes-256-gcm",
 @options={},
 @rotations=[],
 @secret=
  "b991b09ab1a52e6649e5f836c4efcb28ec0d7e899e88be7b072cf752bf2194e8d2600dc524748f67d400a831f967a3a7b7c0b64d0af7b19cc2ee92300aa8c028699ca35ed9bb28f45d6238bf37476832e89638c200efb9ef8dccdf368f920d9d4a6ad941402a6c0ebb078e5b80d2ce76e3dafe45c3d44389c9c3633e710afde2",
 @serializer=Marshal,
 @sign_secret=nil,
 @verifier=ActiveSupport::MessageEncryptor::NullVerifier>
pry(main)> encrypt_salery = encryptor.encrypt_and_sign(salery)
ArgumentError: key must be 32 bytes
from /Users/kotamiyake/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activesupport-5.2.0/lib/active_support/message_encryptor.rb:169:in `key='

 

 

日頃の開発でpumaを使うことが多くなってきたので新たにpuma-devを使い始めることにしました。

puma/puma-dev: A tool to manage rack apps in development with puma
https://github.com/puma/puma-dev

以前使ったことがあったので、とりあえず手元の環境を新しくします。

$ brew upgrade puma-dev
$ puma-dev -uninstall
$ puma-dev -install -d test
$ sudo puma-dev -setup

これでシンボリックリンクを貼り直すだけで.testドメインでアプリを動かすことができるようになりました。

puma-devのREADMEにはHSTSの影響で.testがデフォルトになっていると書かれていたのですが、どうやらhomebrew経由のインストールだと最新版になっていない模様です。

Homebrew pulling older version (default domain is .dev, not .test) · Issue #168 · puma/puma-dev
https://github.com/puma/puma-dev/issues/168

HSTSとはなんぞやというのはWikipediaを参考にしました。

HTTP Strict Transport Security (エイチティーティーピー・ストリクト・トランスポート・セキュリティ、略称 HSTS)とは、WebサーバーがWebブラウザに対して、現在接続しているドメイン(サブドメインを含む場合もある)に対するアクセスにおいて、次回以降HTTPの代わりにHTTPSを使うように伝達するセキュリティ機構である。RFC 6797 で規定されている。

要はセキュリティ上の理由から強制的にHTTPSへリダイレクトする機能らしいです。

その対象に.devドメインも含まれていたので、利便性の理由から.testをデフォルトにしたようです。