随着信息技术和Internet 的迅速发展,信息安全和可靠性问题越来越重要。现在信息安全面临两大基本攻击:被动式攻击(获取消息的内容、业务流分析)和主动攻击(假冒、消息的篡改、业务拒绝)。前者主要靠加密和解密技术进行有效处理,而后者就要靠消息认证来处理。在金融交易、电子商务、电子信件、手机用户信息的确认等领域,数据完整性确认和数据来源的真伪鉴定都是很重要的安全服务。实现这些安全服务的最好方法就是使用加密函数中的单项散列(Hash)函数。单项散列(Hash)函数是一种单项密码体制,它是一个从明文到密文的不可逆函数,也就是说,是无法解密的。通常应用在只需要加密、不需要解密的特殊应用场合。单项散列(Hash)函数H(M)作用于一任意长度的消息M,它返回一固定长度的散列值h:h=H(M)作为初始消息的独一无二的“数字指纹”,从而能保证数据的完整性和惟一性。
1.MD5与SHA-1的比较
由于MD5 与SHA-1均是从MD4 发展而来,它们的结构和强度等特性有很多相似之处,表(1)是对MD5 与SHA-1 的结构比较。SHA-1与MD5 的最大区别在于其摘要比MD5 摘要长 32 比特。对于强行攻击,产生任何一个报文使之摘要等于给定报文摘要的难度:MD5 是2128 数量级的操作,SHA-1 是2160 数量级的操作。产生具有相同摘要的两个报文的难度:MD5是 264 是数量级的操作,SHA-1 是280 数量级的操作。因而,SHA-1 对强行攻击的强度更大。但由于SHA-1 的循环步骤比MD5 多(80:64)且要处理的缓存大(160 比特:128 比特),SHA-1 的运行速度比MD5 慢。
2.算法使用
/**
* MD5字符串加密
*
* @param str
* @return
* @throws NoSuchAlgorithmException
*/
public final static String md5(String str) throws NoSuchAlgorithmException {
final char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
byte[] btInput = str.getBytes();
// 获得MD5摘要算法的 MessageDigest 对象
MessageDigest md5Inst = MessageDigest.getInstance("MD5");
// 使用指定的字节更新摘要
md5Inst.update(btInput);
// 获得密文
byte[] bytes = md5Inst.digest();
StringBuilder strResult = new StringBuilder();
// 把密文转换成十六进制的字符串形式
for (int i = 0; i < bytes.length; i++) {
strResult.append(hexDigits[(bytes[i] >> 4) & 0x0f]);
strResult.append(hexDigits[bytes[i] & 0x0f]);
}
return strResult.toString();
}
/**
* SHA-1字符串加密
*
* @param str
* @return
* @throws NoSuchAlgorithmException
*/
public final static String sha1(String str) throws NoSuchAlgorithmException {
final char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
byte[] btInput = str.getBytes();
// 获得SHA-1摘要算法的 MessageDigest 对象
MessageDigest sha1Inst = MessageDigest.getInstance("SHA-1");
// 使用指定的字节更新摘要
sha1Inst.update(btInput);
// 获得密文
byte[] bytes = sha1Inst.digest();
StringBuffer strResult = new StringBuffer();
// 把密文转换成十六进制的字符串形式
for (int i = 0; i < bytes.length; i++) {
strResult.append(hexDigits[(bytes[i] >> 4) & 0x0f]);
strResult.append(hexDigits[bytes[i] & 0x0f]);
}
return strResult.toString();
}