MessageDigest
メッセージダイジェストについて、初歩的なことですがおさらいしてみました。
メッセージダイジェストはハッシュ関数と呼ばれることの方が多いかもしれませんが、あるデータから一意のハッシュ値を算出するものです。大きなデータをダウンロードしたときに、そのファイルが壊れていないかを簡易的にチェックするチェックサムとして使われたり、一方向関数の性質から暗号処理の一部で使われたりします。詳細については、用語辞典などを参照してください。
良く使われるアルゴリズムに、MD5とSHAがあります。それぞれ派生したアルゴリズムがあります。MD5は最近では脆弱性が指摘されていて、一般にはSHAのビット長が大きいものが使われるようになってきているようです。ここでは、GNUのコマンドとJava6を使用して、実際にメッセージダイジェストを扱ってみます。
GNUコマンド
GNUのコマンドでは、"sha1sum"のような「アルゴリズム+sum」コマンド(coreutilsに含まれています)があります。また、OpenSSLというツールでメッセージダイジェスト機能が利用できます。ここでは前者を使用します。また、コマンドの環境はCygwinとFedoraCore6です。例はCygwinですが、FedoraCoreでも確認しています。
# Cygwinのバージョンチェック Cygwinだけ $ cygcheck -c cygwin bash coreutils Cygwin Package Information Package Version Status bash 3.2.25-17 OK coreutils 6.7-2 OK cygwin 1.5.24-2 OK $ echo $SHELL /bin/bash $ for a in md5 sha1 sha224 sha256 sha384 sha512 > do > echo $a=`echo -n 123 | ${a}sum -t` > done md5=202cb962ac59075b964b07152d234b70 - sha1=40bd001563085fc35165329ea1ff5c5ecbdbbeef - sha224=78d8045d684abd2eece923758f3cd781489df3a48e1278982466017f - sha256=a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3 - sha384=9a0a82f0c0cf31470d7affede3406cc9aa8410671520b727044eda15b4c25532a9b5cd8aaf9cec4919d76255b6bfb00f - sha512=3c9909afec25354d551dae21590bb26e38d53f2173b8d3dc3eee4c047e7ab1c1eb8b85103e3be7ba613b31bb5c9c36214dc9f14a42fd7a2fdb84856bca5c44c2 - $
"-t"オプションは標準入力からデータを取得します。"123"のハッシュ値をそれぞれのアルゴリズムで出力しています。(echoは-nオプションを付けないと改行が含まれてしまいます。)
Java6
Javaでは、java.security.MessageDigestクラスを使います。GNUのコマンドのようなプログラムをJavaで実装してみます。以下のmainメソッドを"jmd"というコマンドで実行できるようにします。
public static void main(String[] args) { if (args.length < 2) { System.err.println("USAGE : jmd algorithm input"); System.exit(0); } try { String algorithm = args[0]; byte[] bytes = args[1].getBytes(); byte[] digest = MessageDigest.getInstance(algorithm).digest(bytes); StringBuilder buffer = new StringBuilder(); for (byte b : digest) { buffer.append(0 <= b && b < 16 ? "0" : ""); buffer.append(Integer.toHexString(b & 0xFF)); } System.out.println(buffer); System.exit(0); } catch (NoSuchAlgorithmException ex) { System.err.println("jmd : " + ex.getMessage()); System.exit(1); } }
Java6で実装されているMessageDigestアルゴリズムは、Java PKCS#11 リファレンスガイド 付録 A:Sun PKCS#11 プロバイダでサポートされるアルゴリズムに記載されています。
では、実行してみます。
$ java -version java version "1.6.0_05-ea" Java(TM) SE Runtime Environment (build 1.6.0_05-ea-b05) Java HotSpot(TM) Client VM (build 1.6.0_05-ea-b05, mixed mode, sharing) $ jmd USAGE : jmd algorithm input $ for a in md2 md4 md5 sha-0 sha-1 sha-224 sha-256 sha-384 sha-512 > do > echo $a=`jmd $a 123` > done md2=ef1fedf5d32ead6b7aaf687de4ed1b71 md5=202cb962ac59075b964b07152d234b70 sha-1=40bd001563085fc35165329ea1ff5c5ecbdbbeef sha-256=a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3 sha-384=9a0a82f0c0cf31470d7affede3406cc9aa8410671520b727044eda15b4c25532a9b5cd8aaf9cec4919d76255b6bfb00f sha-512=3c9909afec25354d551dae21590bb26e38d53f2173b8d3dc3eee4c047e7ab1c1eb8b85103e3be7ba613b31bb5c9c36214dc9f14a42fd7a2fdb84856bca5c44c2 $