Raguonの課題管理帳

だいたい山のこと書いてます

Javaによるメッセージダイジェスト化 - 1

手の内は明かしていきます。

今日の帰りに千葉県民の同期と帰りながら、ハッシュ化について話していた。
たぶんJavaにそんなクラスあるんだろうなーと思ってたら、ホントにあった。

その名もMessageDigestクラス。なかなかストレート。

こやつはnewでインスタンスを生成しない。
これが俗にファクトリーメソッドと呼ばれる輩なのか。
getInstanceメソッドでインスタンスを取得する。

このgetInstanceメソッド、引数にメッセージダイジェストを生成するアルゴリズムを指定する。
ここにはMD2, MD5, SHA-1, SHA-256, SHA-384, SHA-512が指定できるようだ。

ためしに組んでみる。

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class HashTest {
	public static void main(String[] args) throws NoSuchAlgorithmException {

		String mesTest1 = "Raguon is cool man :)";
		byte[] bytes1 = mesTest1.getBytes();
		MessageDigest messageDigest1 = MessageDigest.getInstance("SHA-256");
		byte[] digest1 = messageDigest1.digest(bytes1);

		System.out.println(mesTest1);
		System.out.println(bytes1.length);
		for(int i = 0; i < bytes1.length; i++){
			System.out.print(bytes1[i] + " ");
		}
		System.out.println();
		System.out.println(digest1.length);
		for(int i = 0; i < digest1.length; i++){
			System.out.print(digest1[i] + " ");
		}
		System.out.println();

		String mesTest2 = "Raguon is fool man :)";
		byte[] bytes2 = mesTest2.getBytes();
		MessageDigest messageDigest2 = MessageDigest.getInstance("SHA-256");
		byte[] digest2 = messageDigest2.digest(bytes2);

		System.out.println(mesTest2);
		System.out.println(bytes2.length);
		for(int i = 0; i < bytes2.length; i++){
			System.out.print(bytes2[i] + " ");
		}
		System.out.println();
		System.out.println(digest2.length);
		for(int i = 0; i < digest2.length; i++){
			System.out.print(digest2[i] + " ");
		}
	}
}

イケてないソースコードだけど気にしないでね。

出力結果

Raguon is cool man :)
21
82 97 103 117 111 110 32 105 115 32 99 111 111 108 32 109 97 110 32 58 41
32
-75 -69 -33 21 97 2 -16 122 93 25 -26 -67 -119 69 -93 91 -6 -82 46 82 -9 -30 -118 -55 -84 59 -111 102 44 -37 108 98
Raguon is fool man :)
21
82 97 103 117 111 110 32 105 115 32 102 111 111 108 32 109 97 110 32 58 41
32
44 31 -96 86 77 71 120 113 -12 -26 35 -24 67 -47 -99 -77 -13 47 -79 77 22 48 -62 83 17 -8 -50 81 -39 -119 -76 -62

getInstanceメソッドはNoSuchAlgorithmException(そんなアルゴリズムねーよ例外)という例外を投げるらしい。
面倒なのでそのままスローする。

digestメソッドを使ってダイジェスト計算ができるらしいが、あいにく引数も戻り値もbyte型配列。
まあString型にはbyte型に変換するメソッドあるだろう、と思ってEclipseの予測機能を使ったら、案の定getBytesメソッドとかあったので使った。

getBytesで取得したバイト列は、文字列を単純にbyte型に直すだけらしい。
21文字だから21バイト。

一方、取得したメッセージダイジェストは32バイト=256ビット。
SHA-256の場合、どんな長さで入力しても32バイトのダイジェストとして返してくれる。

結果を見て分かる通り、getBytesで取得したバイト列は途中1文字変えた箇所しか変わっていないが、メッセージダイジェストは全て異なる値となっている。


これは遊びがいがありそう。来週の土日あたりにもう一度いろいろ試したい。


参考ページ

http://lab.moyo.biz/recipes/java/security/msgdigest.xsp

  • MessageDigest (API)

http://java.sun.com/javase/ja/6/docs/ja/api/java/security/MessageDigest.html

http://java.sun.com/javase/ja/6/docs/ja/technotes/guides/security/crypto/CryptoSpec.html

http://java.sun.com/javase/ja/6/docs/ja/technotes/guides/security/StandardNames.html