本系列文章主要總結(jié)了常用的Java加解密技術(shù)。本文介紹消息摘要,包括MD、SHA和MAC,消息摘要是一種不可逆的過程,常用于文件完整性校驗。
MD算法
MD(Message Digest,消息摘要算法)是一種最常見的消息摘要算法,有MD2、MD3、MD4和MD5,其中又屬MD5最為常見。MD系列的消息摘要算法生成128位的摘要數(shù)據(jù)(16個字節(jié),Hex編碼為32個字符)。
使用Java實現(xiàn)
Java本身提供了MD5的實現(xiàn),示例代碼如下,JDK版本是由于JDK沒有提供進制轉(zhuǎn)換,所以需要自己實現(xiàn)進制轉(zhuǎn)換。
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5TestJdk {
public static void main(String[] args)
throws NoSuchAlgorithmException,
UnsupportedEncodingException {
byte[] data = "www.hiwzc.com".getBytes("UTF-8");
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(data);
byte[] digest = md.digest();
System.out.println(toHexString(digest));
}
private static String toHexString(byte[] data) {
String table = "0123456789abcdef";
StringBuilder sb = new StringBuilder();
final int l = data.length;
for (int i = 0; i < l; i++) {
sb.append(table.charAt((0xF0 & data[i]) >>> 4));
sb.append(table.charAt(0x0F & data[i]));
}
return sb.toString();
}
}
使用Bouncy Castle實現(xiàn)
下面的代碼使用開源軟件Bouncy Castle實現(xiàn)MD5消息摘要,使用的版本是1.56。有兩種實現(xiàn)方式,一種是將Bouncy Castle的Provider提供給Java的JCA框架,另一種是使用Bouncy Castle自己的API。
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.digests.MD5Digest;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;
public class MD5TestBC {
public static void main(String[] args)
throws UnsupportedEncodingException, NoSuchAlgorithmException {
// 使用JCA框架
byte[] data = "www.hiwzc.com".getBytes("UTF-8");
MessageDigest md = MessageDigest.getInstance("MD5",
new BouncyCastleProvider());
md.update(data);
byte[] digest = md.digest();
System.out.println(Hex.toHexString(digest));
// 使用Bouncy Castle的API
Digest md5 = new MD5Digest();
md5.update(data, 0, data.length);
byte[] digest2 = new byte[md5.getDigestSize()];
md5.doFinal(digest2, 0);
System.out.println(Hex.toHexString(digest2));
}
}
使用Apache Commons Codec實現(xiàn)
下面的代碼使用開源軟件Apache Commons Codec實現(xiàn)MD5消息摘要,使用的版本是1.10。與Bouncy Castle不同,Apache Commons Code不是一個JCA的Provider,而是封裝了Java的實現(xiàn)。
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.codec.digest.DigestUtils;
public class MD5TestCC {
public static void main(String[] args)
throws UnsupportedEncodingException,
NoSuchAlgorithmException {
byte[] data = "www.hiwzc.com".getBytes("UTF-8");
String md5 = DigestUtils.md5Hex(data);
System.out.println(md5);
}
}
SHA算法
SHA(Secure Hash Algorithm,安全散列算法)是在MD4基礎(chǔ)上發(fā)展起來的新一代消息摘要算法,SHA生成的摘要信息比MD5更長,安全性更高。目前SHA算法有SHA-1、SHA-224、SHA-256、SHA-384、SHA-512。SHA-1生成的消息摘要長度為160位(20個字節(jié),Hex編碼為40個字符),其他的長度和名稱一致,比如SHA-256的摘要長度為256位(32個字節(jié),Hex編碼為64個字符)。
得益于Java提供的JCA框架,SHA256的實現(xiàn)和MD5的實現(xiàn)基本一致,比如SUN實現(xiàn)SHA-256只要把MD5實現(xiàn)的MessageDigest.getInstance("MD5")改為MessageDigest.getInstance("SHA-256")即可。下面看看Bouncy Castle和Apache Comons Codec的實現(xiàn)。
使用Bouncy Castle實現(xiàn)
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;
public class Sha256TestBC {
public static void main(String[] args)
throws UnsupportedEncodingException,
NoSuchAlgorithmException {
// 使用JCA框架
byte[] data = "www.hiwzc.com".getBytes("UTF-8");
MessageDigest md = MessageDigest.getInstance("SHA-256",
new BouncyCastleProvider());
md.update(data);
byte[] digest = md.digest();
System.out.println(Hex.toHexString(digest));
// 使用Bouncy Castle的API
Digest sha256 = new SHA256Digest();
sha256.update(data, 0, data.length);
byte[] digest2 = new byte[sha256.getDigestSize()];
sha256.doFinal(digest2, 0);
System.out.println(Hex.toHexString(digest2));
}
}
使用Apache Commons Codec實現(xiàn)
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.codec.digest.DigestUtils;
public class Sha256TestCC {
public static void main(String[] args)
throws UnsupportedEncodingException,
NoSuchAlgorithmException {
byte[] data = "www.hiwzc.com".getBytes("UTF-8");
String md5 = DigestUtils.sha256Hex(data);
System.out.println(md5);
}
}