哈希算法(散列算法)并不是一个特定的算法而是一类算法的统称。常见的哈希算法:MD5, SHA256
目前主要的哈希算法有两类:MD系列和SHA系列。
MD(Message Digest, 消息摘要)系列有MD4、MD5、HAVAL等
SHA(Secure Hash Algorithm, 安全散列算法)系列有SHA1、SHA256等。
作为加密算法的一种,散列函数是一种单向密码体制,即一个从明文到密文的不可逆映射,只有加密过程,没有解密过程
哈希算法将任意长度的二进制值映射为较短的固定长度的二进制值,这个小的二进制值称为哈希值。哈希值是一段数据唯一且极其紧凑的数值表示形式。如果散列一段明文而且哪怕只更改该段落的一个字母,随后的散列值都将产生不同的值。要找到散列为同一个值的两个不同的输入,在计算上是不可能的,所以数据的散列值可以检验数据的完整性。一般用于快速查找和加密算法。
本质上,散列算法的目的不是为了“加密”而是为了抽取“数据特征”,你也可以把给定数据的散列值理解为该数据的“指纹信息”,一个可靠的散列算法F需要满足:
1. 对于给定的数据M,很容易算出哈希值X=F(M)
2. 根据X无法算出M
3. 很难找到M和N令F(M)=F(N)
HASH+SALT 常见的密码保护!!!
在密码学中,是指通过在密码任意固定位置插入特定的字符串,让散列后的结果和使用原始密码的散列结果不相符,这种过程称之为“加盐”。
比如 md5(md5(password) + salt)
真正的二次哈希是基于加盐的哈希,什么意思呢?对于特定的待散列数据和特定的散列算法,可以知道散列值是一定的,这种情况下如果用散列保护敏感数据(理论上是不合适的,但是国内外存在大量的使用散列来保护用户密码的情况),那就很容易使用字典攻击反向推算,比如我计算123456的SHA256值就可以反推了,解决办法就是先做一次散列,再加一次随机数据以后再做一次散列,随机数据就是所谓的盐。
要增加破解的难度,让我们在密码泄露时多争取点时间,其中的一种方式就是给密码中加点盐(salt),在生成密码的哈希值时,加入一个随机的字符串(salt),然后保存在数据库中。这样对于相同的密码,在数据库中的保存的记录也是不同的。这样对于使用彩虹表破解的黑客来说,破解的成本很高,因为他需要猜测混合salt的算法,同样,暴力破解也变的不太可能。
哈希算法的主要应用场景:加密,文件上传等 ...
在Java中,我们可以基于Apache commons-codec的工具类来实现SHA-256加密
commons-codec
commons-codec
1.13
package com.yiben.tech;
import org.apache.commons.codec.binary.Hex;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* Created by lijie on 2019/10/27.
*/
public class SHAUtils {
public static String getSHA256BasedMD(String originalStr) {
MessageDigest messageDigest;
String encedStr = "";
try {
messageDigest = MessageDigest.getInstance("SHA-256");
byte [] hash = messageDigest.digest(originalStr.getBytes("UTF-8"));
encedStr = Hex.encodeHexString(hash);
} catch (NoSuchAlgorithmException ex) {
ex.printStackTrace();
} catch (UnsupportedEncodingException ex) {
ex.printStackTrace();
}
return encedStr;
}
}