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