消息摘要算法
消息摘要算法的特征是加密过程不需要秘钥,并且加密的数据无法被解密。任何消息经过散列函数处理后,都会获得唯一的散列值,这一过程称为“消息摘要”。
消息摘要算法最著名的是MD5算法和SHA-1算法及其变体。
MD5算法长度为128位(16字节),SHA-1算法长度为160位(20字节),SHA-256算法长度为256位(64字节)。
消息摘要函数是单向函数,只能正向求得密文,无法反向求明文信息。
Java实现
使用JDK自带的java.security.MessageDigest
下的MessageDigest
类。
MessageDigest md = MessageDigest.getInstance("MD5"); // 使用MD5算法
MessageDigest md = MessageDigest.getInstance("SHA-256"); // 使用SHA-256算法
MD5算法
public static String getMD5(String str) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] md5Bytes = md.digest(str.getBytes());
return bytesToHexString(md5Bytes);
}
SHA-256算法
public static String getSHA(String str) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] shaBytes = md.digest(str.getBytes());
return bytesToHexString(shaBytes);
}
为了使用方便,将输出值转换为十六进制保存。
public static String bytesToHexString(byte[] bytes) {
StringBuilder stringBuilder = new StringBuilder();
if (bytes == null || bytes.length <= 0) {
return null;
}
for (byte aByte : bytes) {
int v = aByte & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
}
下面是测试:
public static void main(String[] args) throws NoSuchAlgorithmException {
String str = "1234";
System.out.println(getMD5(str));
System.out.println(getSHA(str));
}
输出:
算法缺陷
MD5算法和SHA-256算法是有缺陷的,可以使用彩虹表进行破解,彩虹表是一个用于散列函数逆运算的预先计算好的表,该表有明文和一一对应的密文,所以能破解上面的算法。
可以通过加盐进行密码加密使得彩虹表失效,但也仅仅是增加了破解的时间。