Javaでパスワードをハッシュ化するのに良い方法を調べたのでメモしておく
要件・方針
- 必要な全情報が攻撃者の手に入ってオフラインで解析されても困らない。
- 強力なHASH関数と、アカウント毎に違うSalt、そしてストレッチングが必要。
- SaltはHASH化されたパスワードと一緒に保管してOK
- Saltとストレッチングの処理は、独自実装ではなく既存のアルゴリズムの既存実装使う
- PBKDF2 とか Bcrypt, Scrypt など。
- JCA(Java Cryptography Architecture) が利用出来るなら最善だろう。そうでなければ著名プロジェクトの物を使いたい
参考
-
http://www.f-secure.com/weblog/archives/00002095.html
- 日本語訳:http://blog.f-secure.jp/archives/50564743.htm
*「SHA-1+salt」じゃなくて、 PBKDF2, Bcrypt, PBMAC を使えってある
*「HMAC」 は「PBMAC」の間違いだと原文にある
- 日本語訳:http://blog.f-secure.jp/archives/50564743.htm
Javaによる実装
まとめ
- java7以前なら、Spring SecurityのBcrypt実装を使うのがよさそう。
- java8以降なら、JCAのPBKDF2をHMAC-SHA-256で利用。またはSpring SecurityのBcrypt実装を使うのがよさそう。
PBKDF2
- JCA(Java Cryptography Architecture) にあるが
- Java6,7 だと「PBKDF2WithHmacSHA1」しかなく、HMAC-SHA1 となるのでお勧めできない
- Java8 だと任意のpseudo-random functionが選べるので、HMAC-SHA-256が使えるので良いと思われる
- ※SaltはEncodeされた結果に入っているので別途保管は不要。またEncode時に自動で安全な物が生成される
Bcrypt
- JCAにはない。
- 信頼出来るプロジェクトの実装としては、Spring (Spring Frameworkの所)の Spring Security http://projects.spring.io/spring-security/ の実装がある
- 強度はパフォーマンスとの兼ね合いなので試験して決める。できる限り強くする
- ※SaltはEncodeされた結果に入っているので別途保管は不要。またEncode時に自動で安全な物が生成される
- ※java8でもこっち使った方が強力だろう
参考:http://terasolunaorg.github.io/guideline/public_review/Security/PasswordHashing.html
Scrypt
- JCAや著名プロジェクトによる実装がない