3-消息摘要
本系列文章主要总结了常用的Java加解密技术。本文介绍消息摘要,包括MD、SHA和MAC,消息摘要是一种不可逆的过程,常用于文件完整性校验。
MD算法
MD(Message Digest,消息摘要算法)是一种最常见的消息摘要算法,有MD2、MD3、MD4和MD5,其中又属MD5最为常见。MD系列的消息摘要算法生成128位的摘要数据(16个字节,Hex编码为32个字符)。
使用Java实现
Java本身提供了MD5的实现,示例代码如下,JDK版本是由于JDK没有提供进制转换,所以需要自己实现进制转换。
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实现
下面的代码使用开源软件Bouncy Castle实现MD5消息摘要,使用的版本是1.56。有两种实现方式,一种是将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实现
下面的代码使用开源软件Apache Commons Codec实现MD5消息摘要,使用的版本是1.10。与Bouncy Castle不同,Apache Commons Code不是一个JCA的Provider,而是封装了Java的实现。
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基础上发展起来的新一代消息摘要算法,SHA生成的摘要信息比MD5更长,安全性更高。目前SHA算法有SHA-1、SHA-224、SHA-256、SHA-384、SHA-512。SHA-1生成的消息摘要长度为160位(20个字节,Hex编码为40个字符),其他的长度和名称一致,比如SHA-256的摘要长度为256位(32个字节,Hex编码为64个字符)。
得益于Java提供的JCA框架,SHA256的实现和MD5的实现基本一致,比如SUN实现SHA-256只要把MD5实现的MessageDigest.getInstance("MD5")
改为MessageDigest.getInstance("SHA-256")
即可。下面看看Bouncy Castle和Apache Comons Codec的实现。
使用Bouncy Castle实现
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实现
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);
}
}