■ はじめに
Java の ハッシュについて、メモ。
目次
【1】ハッシュ 1)特徴 2)用途 3)使用上の注意 【2】MessageDigest・API仕様 【3】サンプル
【1】ハッシュ
* あるデータをハッシュ関数という特別な関数を使うと、 決まった長さのビット列になる、この値を「ハッシュ値」という * ハッシュ値の別名として、 「メッセージ・ダイジェスト (message digest) 」 「フィンガープリント(指紋)」と呼ぶ場合もある ```` http://itpro.nikkeibp.co.jp/article/COLUMN/20060628/241960/ ## 1)特徴
## 2)用途
- ユーザー認証
- デジタル署名(または電子署名) etc...
## 3)使用上の注意
- 以下のURLで言われているが、
http://www.javaroad.jp/bbs/answer.jsp?q_id=20060203152045485
「暗号化」と聞くと元に戻せる、 つまり「複合化」できるイメージを抱いてしまうが、 ハッシュで暗号化すると、基本、元に戻せない => ハッシュ関数は、「不可逆的な一方向の関数」とも呼ばれる。 「一方向」ってことは、元に戻せないってこと。
以下のサイトでは「ハッシュ」と「暗号化」の違いについて書いている。
http://blog.goo.ne.jp/xmldtp/e/b6a697735a597e8e41af460ae2f2875a http://d.hatena.ne.jp/digisecdog/20101119/1290147066
このブログでは、以下のサイトであるとおり、 「暗号化」を「改ざんされたりされないよう、 決まった規則に従ってデータを変換すること。」と定義し タイトルを「ハッシュで暗号化」っとしている (ただ、混同しやすいので意識したほうがいい)
http://e-words.jp/w/E69A97E58FB7E58C96.html # 【2】MessageDigest・API仕様 ** API仕様 ** http://docs.oracle.com/javase/jp/7/api/java/security/MessageDigest.html ** アルゴリズム種類 ** http://docs.oracle.com/javase/jp/7/technotes/guides/security/StandardNames.html#MessageDigest # 【3】サンプル ** CipherHelper.java : ハッシュ値取得クラス **
import java.security.MessageDigest;
public class CipherHelper {
public enum HashAlgorithm { MD2("MD2"), MD5("MD5"), SHA1("SHA-1"), SHA256("SHA-256"), SHA384("SHA-384"), SHA512("SHA-512");
private String value;
private HashAlgorithm(String value) {
this.value = value;
}
public String toString() {
return this.value;
}
}
public static String getHash(String value, HashAlgorithm hashAlgorithm) { String returnValue = null; try { MessageDigest messageDigest = MessageDigest.getInstance(hashAlgorithm.toString()); messageDigest.update(value.getBytes()); byte[] hashValues = messageDigest.digest(); returnValue = DatatypeConverter.printHexBinary(hashValues); } catch (Exception ex) { ex.printStackTrace(); } return returnValue; } }
** Main.java : 使う側 **
public class Main { public static void main(String[] args) { try { String targetValue = "Hellow World!!";
System.out.println("Length : 123456789|123456789|123456789|123456789|123456789+123456789|123456789|123456789|123456789|123456789+123456789|123456789|123456789|123456789|123456789+");
String hashByMD2 =
CipherHelper.getHash(targetValue, HashAlgorithm.MD2);
System.out.println("MD2 : " + hashByMD2);
String hashByMD5 =
CipherHelper.getHash(targetValue, HashAlgorithm.MD5);
System.out.println("MD5 : " + hashByMD5);
String hashBySHA1 =
CipherHelper.getHash(targetValue, HashAlgorithm.SHA1);
System.out.println("SHA1 : " + hashBySHA1);
String hashBySHA256 =
CipherHelper.getHash(targetValue, HashAlgorithm.SHA256);
System.out.println("SHA256 : " + hashBySHA256);
String hashBySHA384 =
CipherHelper.getHash(targetValue, HashAlgorithm.SHA384);
System.out.println("SHA384 : " + hashBySHA384);
String hashBySHA512 =
CipherHelper.getHash(targetValue, HashAlgorithm.SHA512);
System.out.println("SHA512 : " + hashBySHA512);
} catch (Exception e) {
e.printStackTrace();
}
} }
## 出力結果 ** 複雑なアルゴリズムになればなるほど、文字列が長くなる? **
Length : 123456789|123456789|123456789|123456789|123456789+123456789|123456789|123456789|123456789|123456789+123456789|123456789|123456789|123456789|123456789+ MD2 : 752a4aa38b4f6d6401a7658890deba62 MD5 : 22a9f348cff599ff7c2a5caa8f4782fd SHA1 : 94bcd8d0e86d4d6f0517c9e80c82b47dc6fe3707 SHA256 : baa04877dbe56a3941a46869982bb67e641bff08dcb7dbf7a7734421a2ecd3c9 SHA384 : 8c42ffdaa91d995a2214d7a22579c8b4c5b3b38968dc8fb4bfd80cbd8a8f1c342a27c1d86f93d1226c52e06219c4b2f3 SHA512 : a02eb48856dfc85e3875ab19c7f5b3c3e5f38f12fc480e5e7352e77bf96655fa48667d374f6c6caeee34cfece55bc4bad944c9e2d9fdd0d88f90b2955e022bb0
# 参考文献 http://itmemo.net-luck.com/java-messagedigest-hash/ http://www.websec-room.com/2013/02/27/238