アルパカ三銃士

〜アルパカに酔いしれる獣たちへ捧げる〜

saltissimo というハッシュ値作成、比較できるパッケージを作って学んだこと。

saltissimo って何??

github.com

様々なWebサービスにおいて、ユーザーの情報登録で必須になってくるのがパスワードで、それを salt とともにハッシュ化してDBに格納するといったコードを書くことがあります。(少なくとも僕の中では!!)
そこで、毎回書くサービスごとで書くのが面倒なので今回上記のようなパッケージを作成しました。
当初 HMAC を使用してハッシュ値を作成していました。とりあえず完成しましたが、色々不安だったので Reddit へ投稿してみました。それから暫くして、見てみるとコメントが入っていたので覗いてみました。そこには新しい知見がありました!!

ハッシュ値を文字列で比較してはならない

当初ハッシュ値の文字列比較を行う関数を用意していました。
しかし、これはサイドチャネル攻撃の一種であるタイミング攻撃の可能性が含まれているとのことを教えてもらいました。タイミング攻撃については以下が分かりやすかったです。

source.hatenadiary.jp

この攻撃を回避するためにはできる限り双方の比較時間の差を無くすことが解決策としてベストみたいですね。 しかも Go にはそのための関数が既に存在していたことも知ることができました。
ConstantTimeCompare

HMAC を用いてパスワードのハッシュ化を行うことをやめた方が良い

HMAC の方式を利用して salt + パスワードからハッシュ値を作成してもあまり効果がないという論文まであるらしいです。そういうことから HMAC を利用するよりもパスワードをベースとしたハッシュ値を生成する関数を利用することが良いということも教えてもらいました。 一般的なものが PBKDF2, Scrypt で最も最新で最強なのが Argon2 らしいです。 Argon2 に関してはCPU使用率、メモリ使用率などのコストパフォーマンスの面を含めて優秀とのこと。
Go でも Argon2 のラッパーはありましたが、移行性を考えて PBKDF2 を使用して saltissimo を書き直しました。

まとめ

  • ハッシュ値を文字列で比較してはならない
  • HMAC を用いてパスワードのハッシュ化を行うことをやめた方が良い
  • OSS だと指摘してくれる人がいること

最近沢山の人から助けてもらってるので、もっとレベルを上げてPRやアドバイスになるような情報を積極的に送れるようになりたいですね!