1.简介
Hash算法: 又称摘要算法。
- 它的作用:对任意一组输入的数据进行计算,得到一个长度固定的输出算法。
- 哈希算法的目的:检验元数据是否被篡改。
- 哈希算法最重要的特点:输入相同的值经过Hash算法一定获得相同的输出,输入不同的值经过Hash算法大概率得到不同的值(有概率哈希碰撞产生相同的值)。
常见的Hash算法:
常见Hash算法 | 输出长度(位) |
---|---|
MD5 | 128bits |
SHA-1 | 160bits |
RipeMD-160 | 256bits |
SHA-256 | 256bits |
SHA-512 | 512bits |
2.MD5算法实现
- 通过MessageDigest类的单例模式创建其对象;
- 通过对象的update()方法更新原始数据;
- 通过对象的digest()方法加密,返回值为字节数组;
- 可通过StringBuilder类,将其转换成十六进制的字符串;
- MD5加密后的字节数组为16字节,其转换成十六进制的字符串长度为32位。
public static void main(String[] args) throws NoSuchAlgorithmException {
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update("hello".getBytes());
byte[] resultArray = md5.digest();
StringBuilder str = new StringBuilder();
for (byte b : resultArray) {
str.append(String.format("%02x", b));
}
System.out.println(str);
}
执行结果:
5d41402abc4b2a76b9719d911017c592
注意:结果中的abcdef可不是字母,而是十六进制!!
2.SHA-1算法实现
- 通过MessageDigest类的单例模式创建其对象;
- 通过其对象的update()方法更新原始数据;
- 通过其对象的digest()方法加密,其返回值为字节数组
- 通过StringBuilder类,将字节数组转换成字符串;
- SHA-1算法极爱后的字节数组为20字节,其转换成十六进制的字符串长度为40位。
String passworf = "hello";
MessageDigest digest = MessageDigest.getInstance("SHA-1");
digest.update(passworf.getBytes());
byte[] digestArray = digest.digest();
StringBuilder str = new StringBuilder();
for (byte b : digestArryay) {
str.append(String.format("%02x", b));
}
System.out.println(str);
执行结果:
aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
小结:
哈希算法加密中的MD5算法思路和SHA-1算法思路大同小异,两者除了对铭文进行摘要加密还可以进行“加盐”;通过获取随机的数据,将此数据更新至明文中,一起加密;可在一定程度上防御“彩虹表”的攻击。
3.HmacMD5算法
在Hmac算法加密时,分成密钥和加密两个部分:
-
生成密钥:
1)通过KeyGenerator类的单例模式创建其对象;
2)其对象通过generateKey()方法生成Key;
3)通过Key的getEncoded()方法生成密钥的字节数组;
4)通过StringBuilder类,将密钥的字节数组转换成十六进制的字符串。
-
加密:
1)通过Mac类的单例模式创建其对象
2)通过对象的init()方法初始化密钥
3)通过对象的update()方法更新数据
4)通过对象的doFinal()方法加密,其返回值为加密的字节数组
5)通过StringBuilder类,将加密的字节数组转换成十六进制的字符串。
-
生成的密钥的字节数为64字节,其加密后的字节数组为16字节。
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException {
String password = "hello";
// 1.生成密钥
KeyGenerator keyGen = KeyGenerator.getInstance("HmacMD5");
SecretKey key = keyGen.generateKey();
byte[] keyByteArray = key.getEncoded();
// 2.加密
Mac mac = Mac.getInstance("HmacMD5");
mac.init(key);
mac.update(password.getBytes());
byte[] resultArray = mac.doFinal();
StringBuilder str = new StringBuilder();
for (byte b : resultArray) {
str.append(String.format("%02x", b));
}
System.out.println("加密的内容:" + str);
}
执行结果:
加密的内容:4d84e614aeb1b19e2fe25353306e8012
4.RipeMD160算法实现
此算法的加密基于BouncyCastle提供的第三方库
- 注册BouncyCastle提供的注册类对象BouncyCastleProvider;
- 通过MessageDigest类的单例模式创建其对象;
- 通过其对象的update()方法,更新原始数据;
- 通过其对象的digest()方法,进行加密,其返回值为字节数组;
- 可通过BigInteger()方法,将字节数组转换成十六进制的字符串;
- 加密后字节数组为20字节,其转换成十六进制为40位。
public static void main(String[] args) throws NoSuchAlgorithmException {
// 添加第三方库的对象
Security.addProvider(new BouncyCastleProvider());
MessageDigest digest = MessageDigest.getInstance("RipeMD160");
digest.update("hello".getBytes());
byte[] result = digest.digest();
String hex = new BigInteger(1, result).toString(16);
System.out.println("字符串的内容:" + hex);
}
执行结果:
字符串的内容:108f07b8382412612c048d07d13f814118445acd
小结:
哈希算法进行加密,都是摘要加密;加密后不可逆,也就是不可通过解密得到明文。以上就是常见的集中哈希算法。
整理完毕,完结撒花~
参考文章:
1.用Java实现常见的哈希算法,https://blog.csdn.net/m0_58743727/article/details/125963627
2.Java实现哈希算法,https://blog.csdn.net/qq_55135629/article/details/125921134