消息摘要算法是单向不可逆的,无法通过加密后的散列值反推原始值,相同的内容用同样的摘要算法获得的散列值是一样的,所以常用于验证数据的完整性。
该算法主要分为三大类:MD(Message Digest,消息摘要算法)、SHA(Secure HashAlgorithm,安全散列算法)和MAC(Message Authentication Code,消息认证码算法)。MD系列算法包括MD2、MD4和MD5共3种算法;SHA算法主要包括其代表算法SHA-1和SHA-1算法的变种SHA-2系列算法(包含SHA-224、SHA-256、SHA-384和SHA-512);MAC算法综合了上述两种算法,主要包括HmacMD5、HmacSHA1、HmacSHA256、HmacSHA384和HmacSHA512算法。这节主要记录下JDK8对这些算法的支持情况。
消息摘要算法的结果我们一般将其转换为16进制字符串,方便阅读传输。
MD系列算法
MD5算法是MD系列算法的代表,由MD2、MD4等算法演变而来。无论采用哪种MD算法,结果都是32字节的16进制字符串。JDK8只支持MD2和MD5两种MD算法。
新建一个maven项目,引入common-codec依赖(包含一些加解密工具类,用于增强JDK或者简化JDK相关加解密API):
1 | <dependency> |
JDK8中,MD系列算法的实现是通过MessageDigest类来完成的,下面演示下使用JDK8原生API实现MD2和MD5加密(算法名称不区分大小写)。
MD2:
1 | import org.apache.commons.codec.binary.Hex; |
运行结果:
1 | a9046c73e00331af68917d3804f70655 |
MD5(只需要将算法改为md5即可):
1 | import org.apache.commons.codec.binary.Hex; |
运行结果:
1 | 5d41402abc4b2a76b9719d911017c592 |
common-codec的DigestUtils也提供了MD2和MD5算法相关方法:
1 | import org.apache.commons.codec.digest.DigestUtils; |
common-codec并没有自己实现相关算法,而是对JDK原生API进行封装,使用起来更方便。
SHA系列算法
SHA算法是基于MD4算法实现的,作为MD算法的继任者,成为了新一代的消息摘要算法的代表。SHA与MD算法不同之处主要在于摘要长度,SHA算法的摘要更长,安全性更高。
SHA算法家族目前共有SHA-1、SHA-224、SHA-256、SHA-384和SHA-512五种算法,通常将后四种算法并称为SHA-2算法。
JDK8支持SHA-1、SHA-256、SHA-384、SHA-224和SHA-512五种算法,其中SHA的写法等价于SHA-1。JDK8中,SHA系列算法的实现也是通过MessageDigest类来完成的:
1 | import org.apache.commons.codec.binary.Hex; |
运行结果:
1 | aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d |
剩下的几种算法可以自己尝试。
common-codec同样也提供了SHA相关算法的API:
1 | import org.apache.commons.codec.digest.DigestUtils; |
MAC系列算法
MAC算法结合了MD和SHA算法的优势,并加入秘钥的支持,是一种更为安全的消息摘要算法。因为MAC算法融合了秘钥散列函数(keyed-Hash),通常我们也把MAC称为HMAC(keyed-Hash Message Authentication Code)。
MAC算法主要集合了MD和SHA两大系列消息摘要算法。MD系列算法有HmacMD2、HmacMD4和HmacMD5三种算法;SHA系列算法有HmacSHA1、HmacSHA224、HmacSHA256、HmacSHA384和HmacSHA512五种算法。
JDK8支持了HmacMD5、HmacSHA1、HmacSHA224、HmacSHA256、HmacSHA384和HmacSHA512这六种MAC算法,通过Mac类实现。
1 | import org.apache.commons.codec.binary.Base64; |
输出结果:
1 | PCg3+Q7i/C0ahZ74Vo3Nl/2wBvHnsdycoSmoAXzuxSwc5DVc1rWyHKHdt1XzlanT5GdJiKkcKhCwXGm7iN+udA== |
实际应用
在Tomcat下载页面:https://tomcat.apache.org/download-70.cgi中,我们可以查看相关文件的摘要:
我们将32-bit Windows zip这个文件下载下来,计算出这个文件的sha512值:
1 | import org.apache.commons.codec.binary.Hex; |
结果:
1 | b7a3b0629dad0d9684bc57a5d18251e38bafa172fcffeac06f7e3c40884f2afc099e7c0143a0471639887b8294c8135c35d1f1ac24f1637dee3c2b3a06aa3aa5 |
这和页面https://downloads.apache.org/tomcat/tomcat-7/v7.0.105/bin/apache-tomcat-7.0.105-windows-x86.zip.sha512上显示的一致,说明我们下载的文件在传输过程中没有被篡改。
《Java加密与解密的艺术》读书笔记