上一篇文章中介绍了基本的单向加密算法 — —
MD5,也大致的说了说它实现的原理。这篇文章继续之前提到的单向加密,主要讲的是 SHA,同 MD5 一样,SHA 同样也是一个系列,它包括 SHA-1,SHA-224,SHA-256,SHA-384,和 SHA-512 等几种算法。其中,SHA-1,SHA-224 和 SHA-256 适用于长度不超过 2^64 二进制位的消息。SHA-384 和 SHA-512 适用于长度不超过 2^128 二进制位的消息。
SHA算法的基本概念
SHA,全称为“Secure Hash Algorithm”,中文名“安全哈希算法”,主要适用于数字签名标准(Digital Signature Standard DSS)里面定义的数字签名算法(Digital Signature Algorithm DSA)。对于长度小于 2^64 位的消息,SHA1 会产生一个 160 位的消息摘要。
该算法的思想是接收一段明文,然后以一种不可逆的方式将它转换成一段(通常更小)密文,也可以简单的理解为取一串输入码(称为预映射或信息),并把它们转化为长度较短、位数固定的输出序列即散列值的过程。
SHA-1 有两个特点:
- 不可以从消息摘要中复原信息
- 两个不同的消息,不会产生同样的消息摘要
SHA算法的种类
SHA-1 与 MD5 的比较
因为二者均由 MD4 导出,SHA-1 和 MD5 彼此很相似。相应的,他们的强度和其他特性也是相似,但还有以下几点不同:
- 对强行攻击的安全性
- 对密码分析的安全性
由于 MD5 的设计,易受密码分析的攻击,SHA-1 显得不易受这样的攻击。
- 速度
在相同的硬件上,SHA-1 的运行速度比 MD5 慢。
SHA系列算法编程使用
SHA系列算法使用代码
import java.security.MessageDigest;
public class SHAUtils {
/**
* SHA算法
*
* @param data
* @return
*/
public static String encryptSHA(byte[] data) {
try {
// 判断数据的合法性
if (data == null) {
throw new RuntimeException("数据不能为NULL");
}
// 获取SHA算法的类型
MessageDigest sha = MessageDigest.getInstance("SHA-512");
// 加入数据
sha.update(data);
// 获取消息摘要
byte[] resultBytes = sha.digest();
// 将字节数组转换为16进制
String resultString = fromBytesToHex(resultBytes);
// 返回
return resultString;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* SHA算法
*
* @param data
* @return
*/
public static String encryptSHA(String data) {
try {
// 判断数据的合法性
if (data == null) {
throw new RuntimeException("数据不能为NULL");
}
// 获取SHA算法的类型
MessageDigest sha = MessageDigest.getInstance("SHA-512");
// 加入数据
sha.update(data.getBytes());
// 获取消息摘要
byte[] resultBytes = sha.digest();
// 将字节数组转换为16进制
String resultString = fromBytesToHex(resultBytes);
// 返回
return resultString;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 将字节数组转化为16进制
*
* @param resultBytes
* @return
*/
private static String fromBytesToHex(byte[] resultBytes) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < resultBytes.length; i++) {
if (Integer.toHexString(0xFF & resultBytes[i]).length() == 1) {
builder.append("0").append(
Integer.toHexString(0xFF & resultBytes[i]));
} else {
builder.append(Integer.toHexString(0xFF & resultBytes[i]));
}
}
return builder.toString();
}
}
测试代码
public class Test {
// 待加密的明文
public static final String DATA = "test";
public static void main(String[] args) throws Exception {
/* Test SHA */
String shaResult = SHAUtils.encryptSHA(DATA.getBytes());
System.out.println(DATA + ">>>SHA>>>" + shaResult);
}
}