※開発の最終段階でハッシュ化することをお薦めします。
Apache Commons CodecのDigestUtilsクラスを使用する方法を紹介します。
上記サイトからApache Commons Codecの最新バージョンのBinariesをダウンロードし、その中のjarファイルをプロジェクトのWEB-INFの中のlibフォルダにコピーしてください。
ハッシュ関数には、同一性(同じデータからは常に同じダイジェストが出力される)、一方向性(ダイジェストから元のデータを導き出すことは不可能)といった性質が求められます。
したがって自作するよりもライブラリを利用することを強く推奨します。
今回は、Apache CommonsのDigestUtils.sha256Hex()メソッドを使っています。
なお、sha256はハッシュアルゴリズムでも最もよく使われているもので電子政府推奨暗号リスト - CRYPTRECにも掲載されています。
import org.apache.commons.codec.digest.DigestUtils; // org.apache.commons.codec.digestパッケージからDigestUtilsクラスをインポートします。このクラスにはメッセージダイジェストアルゴリズムのユーティリティメソッドが含まれています。
public class DigestUtilsTest {
public static void main(String[] args) {
System.out.println(DigestUtils.sha256Hex("123456789")); // 文字列"123456789"に対してSHA-256ハッシュを計算し、その結果を16進数の文字列としてコンソールに出力します。
System.out.println(DigestUtils.sha256Hex("123456789" + "salt")); // 文字列"123456789"と"salt"を連結した文字列に対してSHA-256ハッシュを計算し、その結果を16進数の文字列としてコンソールに出力します。これはソルティングと呼ばれ、同じ元のテキストに対するハッシュ値の予測を難しくします。
}
}
<実行結果>
15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225 ab03db0c39851456931b33c525bf70aa4998172865c9adebf930894c4fe8e51f |
6行目の例のようにハッシュ化をしただけの単純なパスワードはレインボーテーブル攻撃で破られてしまいます。
そこで、7行目の例のようにソルトを加えたり、以下の例のようにストレッチングをすることをお勧めします。
注)ソルトはパスワードごとに変化させることが望ましいです。
ストレッチを1万回かけたサンプルコードです。
import org.apache.commons.codec.digest.DigestUtils; // org.apache.commons.codec.digestパッケージからDigestUtilsクラスをインポートします。このクラスにはメッセージダイジェストアルゴリズムのユーティリティメソッドが含まれています。
public class DigestUtilsTest2 {
public static void main(String[] args) {
String pass = "123456789"; // オリジナルのパスワードを定義します。
for (int i = 0; i < 10000; i++) { // 10,000回ループを開始します。この数は、ハッシュを再計算する回数を示します。
pass = DigestUtils.sha256Hex(pass); // 各ループで、前のハッシュの結果に対して新たにSHA-256ハッシュを計算します。この結果は、次のループで使用されます。
}
System.out.println(pass);
}
<実行結果>
56708be877dd36e710637b4f39843996ac2a08a163e3493150243ccc9ba45361 |
なお、ハッシュ化したパスワードは元に戻せません。
ログイン処理などでパスワードの一致を調べる場合には、新しく入力されたパスワードをハッシュ化してデータベースなどに格納されているハッシュ化済みのパスワードと比較します。
以上。