说明:以下代码基于jdk8,bouncyCastle版本bcprov-jdk15to18-1.66.jar
一、简述
消息摘要算法又叫散列算法,核心在于散列函数的单向性,这也是摘要算法安全性的根本所在。
消息摘要包含MD(Message Digest,消息摘要算法)、SHA(Secure Hash Algorithm,安全散列算法)、MAC(Message Authentication Code, 消息认证码算法)三大系列,用于验证数据的完整性。
二、MD算法
简介
MD算法中的MD5算法是目前广泛使用的杂凑算法之一,是消息摘要算法的首要代表
MD2
1989年又非对称算法RSA发明人之一的罗纳德·李维斯特开发,该算法先对信息进行补位,使字节长度为16的倍数,再以一个16位的检验和作为补充信息追加到原信息末尾,根据新信息计算一个128位的散列值。
MD4
MD4比MD2有着更高的安全性,该算法仍是补位,不同的是补位后使其字节长度加上448个字节后为512的倍数(字节长度 mod 512 = 448),虽然细节不同,但是结果还是128位的散列值。
MD5
MD5经MD2、MD3、MD4发展而来,安全更高,但效率略逊于MD4,MD算法的结果均为128位散列值
代码
jdk
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
byte[] bytes = messageDigest.digest("消息摘要算法".getBytes());
System.out.println(Hex.toHexString(bytes));
Bouncy castle
Security.addProvider(new BouncyCastleProvider());
Digest md5Digest = new MD5Digest();
byte[] b = "消息摘要算法".getBytes();
md5Digest.update(b, 0, b.length);
byte[] bb = new byte[md5Digest.getDigestSize()];
md5Digest.doFinal(bb, 0);
System.out.println(Hex.toHexString(bb));
Commons Code
String md5Str = DigestUtils.md5Hex("消息摘要算法".getBytes());
System.out.println(md5Str);
三、SHA算法
简介:
SHA算法由MD4发展而来,但是SHA的摘要长度更长,安全性更好。SHA目前有SHA-1、SHA2、SHA-3,其中SHA-2和SHA-3根据摘要长度的不同,分为SHA-224、SHA-256 、SHA-384、SHA-512
jdk(jdk只支持SHA1和SHA2算法)
MessageDigest messageDigest = MessageDigest.getInstance("SHA-512");
byte[] bytes = messageDigest.digest("消息摘要算法".getBytes());
System.out.println(Hex.toHexString(bytes));
bouncy castle
Security.addProvider(new BouncyCastleProvider());
SHA512Digest sha512Digest = new SHA512Digest();
byte[] b = "消息摘要算法".getBytes();
sha512Digest.update(b, 0, b.length);
byte[] bb = new byte[sha512Digest.getDigestSize()];
sha512Digest.doFinal(bb, 0);
System.out.println(Hex.toHexString(bb));
Comons Code
String s = DigestUtils.sha512Hex("消息摘要算法".getBytes());System.out.println(s);
四、mac算法
简介:MAC算法结合了MD5和SHA算法的优势,并加入了秘钥的支持,是一种更为安全的消息摘要算法。
jdk
KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacSHA1");
SecretKey secretKey = keyGenerator.generateKey();
byte[] bytes = secretKey.getEncoded();
Mac mac = Mac.getInstance("HmacSHA1");mac.init(secretKey);
byte[] bb = mac.doFinal(bytes);
System.out.println(Hex.toHexString(bb));
boubcy castle
KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5");
SecretKey secretKey = keyGenerator.generateKey();
byte[] bytes = secretKey.getEncoded();
Security.addProvider(new BouncyCastleProvider());
Mac mac = Mac.getInstance("HmacMD5", new BouncyCastleProvider());
mac.init(secretKey);
byte[] bb = mac.doFinal("测试测试测试".getBytes());
System.out.println(Hex.toHexString(bb));
五、其他消息摘要算法
- RipeMD:在MD4,MD5缺陷分析的基础上改进而来,根据摘要长度区分,类似于SHA算法
算法 | 摘要长度 | 备注 |
---|
RipeMD128 | 128 | Bouncy Castle实现 |
RipeMD160 | 160 | Bouncy Castle实现 |
RipeMD256 | 256 | Bouncy Castle实现 |
RipeMD320 | 320 | Bouncy Castle实现 |
HmacRipeMD128 | 128 | Bouncy Castle实现 |
HmacRipeMD160 | 160 | Bouncy Castle实现 |
Security.addProvider(new BouncyCastleProvider());
MessageDigest messageDigest = MessageDigest.getInstance("RipeMD320");
byte[] mb = messageDigest.digest("测试测试测试".getBytes());
System.out.println(Hex.toHexString(mb));
Digest digest = new RIPEMD320Digest();
byte[] bytes = "测试测试测试".getBytes();
digest.update(bytes, 0, bytes.length);
byte[] bb = new byte[digest.getDigestSize()];
digest.doFinal(bb, 0);
System.out.println(Hex.toHexString(bb));
Security.addProvider(new BouncyCastleProvider());
KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacRipeMD128");
SecretKey secretKey = keyGenerator.generateKey();
Mac mac = Mac.getInstance("HmacRipeMD128");
mac.init(secretKey);
byte[] bytes = mac.doFinal("测试测试测试".getBytes());
System.out.println(Hex.toHexString(bytes));
- Tiger:号称最快的hash算法,专门为64位机器做了优化,长度为192
Security.addProvider(new BouncyCastleProvider());
MessageDigest messageDigest = MessageDigest.getInstance("Tiger");
byte[] mb = messageDigest.digest("测试测试测试".getBytes());
System.out.println(Hex.toHexString(mb));
Digest digest = new TigerDigest();
byte[] bytes = "测试测试测试".getBytes();
digest.update(bytes, 0, bytes.length);
byte[] bb = new byte[digest.getDigestSize()];
digest.doFinal(bb, 0);
System.out.println(Hex.toHexString(bb));
- Whirlpool:被列入ISO标准,使用AES相同的转化技术,极大提高安全性,被称为最安全的摘要算法
Security.addProvider(new BouncyCastleProvider());
MessageDigest messageDigest = MessageDigest.getInstance("Whirlpool");
byte[] mb = messageDigest.digest("测试测试测试".getBytes());
System.out.println(Hex.toHexString(mb));
Digest digest = new WhirlpoolDigest();
byte[] bytes = "测试测试测试".getBytes();
digest.update(bytes, 0, bytes.length);
byte[] bb = new byte[digest.getDigestSize()];
digest.doFinal(bb, 0);
System.out.println(Hex.toHexString(bb));
六、循环冗余校验算法-CRC算法
![在这里插入图片描述](https://img-blog.csdnimg.cn/7eb570765f1f4ada8eead93f9ee2c9e1.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5LiJ6KeCcw==,size_20,color_FFFFFF,t_70,g_se,x_16)
简述:
CRC(Cyccli Redundancy Check, 循环冗余校验)可以根据数据产生剪短固定位数的一种散列函数,用来检测或校验数据传输或保存后出现的错误。
CRC发展历史
- CRC-1:主要用于硬件,常说的奇偶校验码
- CRC-32-IEEE 802.3:用于通信领域的差错校验
- CRC-32-Adler:CRC-32的一个变种
- CRC-128:演变为如今的MD算法,消息摘要值为128位的二进制
- CRX-160:演变为如今的SHA算法,消息摘要值为160位的二进制
CRC32 crc32 = new CRC32();
crc32.update("测试测试".getBytes());
long l = crc32.getValue();
String ss = Long.toHexString(l);
System.out.println(ss);
七、实例:文件校验
![在这里插入图片描述](https://img-blog.csdnimg.cn/bc65b09239ca411392b2d507a43ea9b6.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5LiJ6KeCcw==,size_20,color_FFFFFF,t_70,g_se,x_16)
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
FileInputStream fileInputStream = new FileInputStream(new File("E:/mysql-installer-web-community-8.0.27.1.msi"));
int length = fileInputStream.available();
DigestInputStream digestInputStream = new DigestInputStream(fileInputStream, messageDigest);
byte[] bb = new byte[length];
digestInputStream.read(bb);
digestInputStream.close();
byte[] bytes = digestInputStream.getMessageDigest().digest();
System.out.println(Hex.toHexString(bytes));
44b7f3e4c1bdcc641621cfaa31ea18f4
Process finished with exit code 0