はじめに
「PHPer もすなる Argon2id といふものを、Railserもしてみむとてするなり。」とは紀貫之は言わなかっただろうけど、Argon2 を Ruby on Rails に導入したいと思ったのさ。
そもそも Argon2 とはなにか
- Wikipedia の記事「Argon2」を読んでね!
- Bcrypt は2020年でも安全だが、さすがに20年使われてきたパスワードを保存するハッシュ関数を使い続けるのは心もとない
- PHP 界隈では Argon2 が利用されているし、もう5年ほど利用されているので、もう利用してもよいのでは
Bcrypt vs Argon2
- Rails から使う用法としては、両方ともパスワードを安全にハッシュ化する関数である
- 2020年春の時点では、両方とも安全とされている
- Bcrypt のメリット・デメリット
- Rails で標準採用されている
- 文字数制限が不安視されている
- see also → bcryptの72文字制限をSHA-512ハッシュで回避する方式の注意点
- Argon2
- 新しいハッシュ関数
- 文字数制限が無い
- PHPでは標準採用されたみたい
- 心配なら Bcrypt にかけたハッシュを Argon2 で再度ハッシュ化したらいいのかな?
- 逆はダメ、絶対!
やりたいこと
- Ruby on Rails 6 に Argon2id を導入したい
- だいたい Rails で bcrypt が標準だけど、それと同じ感じで利用できるようにしたい
- 利用する Gem は ruby-argon2 を使う
レッツトライ!
$ rails g model staff name:string email:string password_digest:string
$ rails db:migrate
としておく。ここまでは bcrypt を導入するのと同じ。次は rails c
で irb でためすことにする。
> h = Argon2::Password.new(t_cost: 2, m_cost: 16)
> h.create("password")
=> "$argon2i$v=19$m=65536,t=2,p=1$jL7lLEAjDN+pY2cG1N8D2g$iwj1ueduCvm6B9YVjBSnAHu+6mKzqGmDW745ALR38Uo"
> Argon2::Password.verity_password('password', h)
=> true
> Argon2::Password.verify_password('qwerty', h)
=> false
> s = Staff.new(name:"jhon", email:'jhon@example.com')
> s.password_digest = h.create("password")
> s.save
> s = Staff.last
> Argon2::Password.verify_password('password', s.password_digest)
=> true
> Argon2::Password.verify_password('qwerty', s.password_digest)
=> false
それほど has_secure_password
を使って Bcrypt を使うのと違いがない感じですかね。
おわりに
途中でやる気がなくなったので、モデル層だけ Rails に Argon2 を導入するところでとどまってしまった。コードは Github にアップしているので、気になる方は確認ください。