S-JIS[2008-08-15] 変更履歴
JavaでMD5やSHA-1といったメッセージダイジェスト(固定長のハッシュ値)を取得するサンプル。
(MD5よりはSHAの方が強固らしい)
import java.security.MessageDigest; import java.security.NoSuchAlgorithmException;
public byte[] digest(String str) { MessageDigest md; try { md = MessageDigest.getInstance("SHA"); //あるいはMD5など→アルゴリズム名 } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } System.out.println(md.getAlgorithm()); md.update(str.getBytes()); return md.digest(); }
public void printDigest(String str) { System.out.println("文字列:" + str); byte[] hash = digest(str); System.out.println(hash.length); System.out.println(new HexDumpEncoder().encode(hash)); }
実行結果:
文字列:abc SHA 20 0000: A9 99 3E 36 47 06 81 6A BA 3E 25 71 78 50 C2 6C ..>6G..j.>%qxP.l 0010: 9C D0 D8 9D
文字列:abc MD5 16 0000: 90 01 50 98 3C D2 4F B0 D6 96 3F 7D 28 E1 7F 72 ..P.<.O...?.(..r
どんな長さのデータを渡しても、SHA-1では20バイト、MD5では16バイトになる。
update()はdigest()を呼び出すまで複数回呼べる。
MessageDigestインスタンスを使い回したいなら、digest()を呼び出すと自動的に計算結果がリセットされるので、そのまま次のデータをupdate()に渡せばよい。
reset()というメソッドもあるが、update()を中断させる為のものなので、digest()の後で呼び出す必要は無い。
ただ、MessageDigestがスレッドセーフかどうかは(Javadocに特に記述が無いので)分からないけど。
MessageDigestに指定できる名前はJava暗号化アーキテクチャー標準アルゴリズム名のドキュメントに載っている。
名前 | ハッシュ長 (バイト数) |
JDK |
---|---|---|
MD2 | 16 | 1.5〜1.6 |
MD5 | 16 | 1.4〜1.6 |
SHA-1 SHA SHA1 |
20 | 1.4〜1.6 |
SHA-256 | 32 | 1.5〜1.6 |
SHA-384 | 48 | 1.5〜1.6 |
SHA-512 | 64 | 1.5〜1.6 |
また、以下のようにして調べることも出来る。
Set names = Security.getAlgorithms("MessageDigest"); for (Iterator i = names.iterator(); i.hasNext();) { String name = (String) i.next(); System.out.println(name); }
JDK1.6の実行結果:
SHA-256 SHA-512 SHA SHA-384 MD5 MD2