S-JIS[2008-08-15] 変更履歴

ダイジェスト(MD5・SHA)

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

Java目次へ戻る / 技術メモへ戻る
メールの送信先:ひしだま