-
2018-12-02 15:32:44
在上一篇文章 【算法大杂烩】常见算法的归类和总结——非对称加密算法 中我们简要介绍了常见的非对称加密算法的相关知识。这次我们乘胜追击,介绍【信息摘要算法】, 通过本文的阅读,你可以了解到以下知识:
- 什么是信息摘要算法?
- 常见的信息摘要算法有哪些以及它们的特性和区别是什么?
- 信息摘要算法的应用场景有哪些?
什么是信息摘要算法?
信息摘要算法是一种对“信息”进行【摘要化】处理的算法。通俗地来说,就好比本文,假设它很长,那么读者在第一时间看到它的时候并不会完全阅读全文,而是往往会先去读一下文章的【摘要】,通过文章的摘要部分,简要了解下文章的主要内容。类似地,在信息密码学领域,同样有这种的操作,这就是信息摘要算法的产生背景。
假设有一段数据(专业术语叫“消息”),经过【信息摘要算法】处理后,它将变成一段固定长度的【信息摘要】,用公式表示如下,其中M表示消息原文,D表示输出的消息摘要,P表示信息摘要算法。
- P(M with any length) = D(with fixed length)
通过公式,我们可以很直观地看出,信息摘要算法的输入数据长度是可以为任意长度,但是在实际使用的过程中,倘若输入数据的长度过于长,我们会采用将输入数据块采用数据分组的方式一步步输入,最后得到信息摘要结果的输出。而输出的信息摘要,通常都是固定长度的,至于信息摘要结果的固定长度是多少,是与具体的摘要算法相关的,下文会详细介绍各种信息摘要算法的摘要输出情况。
还有一点,公式中并没有体现“加密和解密的相互过程”,也就是说【信息摘要算法是单向的,不可逆的】。严格来说,它并不是一种【加密】算法,仅仅是【摘要】算法。由于它计算的不可逆性,所以经信息摘要算法计算出来的信息摘要D,一定程度上就代表了信息原文M。倘若有原文M1和原文M2,经过相同的信息摘要算法P,得到相同的信息摘要D,这种情况在密码学上,我们称之为【碰撞】。一般而言, 好的摘要算法,没有人能从中找到【碰撞】或者说极度难找到。虽然【碰撞】是肯定存在的(碰撞即不同的内容产生相同的摘要),但因目前信息科学发达程度非常高,计算机的运算能力得到了前所未有的提升,仅通过计算机运算的暴力破解,某些较弱的信息摘要算法就能被【碰撞】成功。
常见的信息摘要算法
常见的信息摘要算法有:MD2/4/5、SHA1/SHA224/SHA256/SHA384、SM3算法、MAC算法等。
MD(Message Digest):消息摘要
MD算法,是诞生于比较早的消息摘要算法,在网络应用上也比较常见,比如在某个网站上下载一个文件,通常它会标识该文件的MD5值,当下载者完成下载文件到本地之后,使用工具对下载的文件执行MD5计算,求出一个MD5摘要值,与网站上给出的参考MD5值进行对比;如果两者相等,则表示下载的文件是可靠的,没有被篡改过的;反之,如果MD5值对不上,则表明下载的文件是被篡改过的,可能是网络攻击者投放的病毒携带文件或者是在下载的过程中文件出现了损坏等情况,此时应该对文件进行删除操作。
MD系列的算法主要有MD2、MD4、MD5,数字值越大表示MD算法的版本越高,从安全性上说:MD5 > MD4 > MD2,自然破解难度MD5是最高的。
MD系列的信息摘要算法,输出的信息摘要长度都是固定的128bits,即16字节;当不同的信息输入时,产生的信息摘要也不相同;反之,当信息摘要相同,我们可以认为信息的明文是相同的。
SHA(Secure Hash Algorithm):安全散列
SHA系列的算法从版本上划分有SHA-1和SHA-2;SHA-1和SHA-2是该算法的两个不同版本。它们两者之间在构造上(散列结果是怎样被原始数据创建出来的)和签名的位数上都有不同和签名的位长。你应该把SHA-2看作是SHA-1的继承者,因为这是一个整体上的改进。
SHA-1就是我们常见到的SHA1;SHA-2主要有SHA224、SHA256、SHA384、SHA512等等,不同的数字代表信息摘要输出的位数。与MD系列算法类似,数字值越高表示摘要算法的安全性越高,计算的复杂性也越大;但不同于MD算法的是,SHA算法每个算法输出的信息摘要长度是不一样的。
- SHA1,产生的信息摘要为160bits,即20字节
- SHA224,产生的信息摘要为224bits,即28字节
- SHA256,产生的信息摘要为256bits,即32字节
- SHA384,产生的信息摘要为384bits,即48字节
- SHA512,产生的信息摘要为512bits,即64字节
更为详细的SHA算法介绍,可以参考: SHA算法 - block2016 - 博客园
SM(Shangyong Mima):国密算法,即商用密码
经查证,国密算法的英文字母缩写SM,其实是【商用密码】的中文拼音首字母简写。国密即国家密码局认定的国产密码算法,即商用密码。
在国密算法的列表中,SM3算法就是实现了类似MD算法和SHA算法的信息摘要算法。它和其他2种摘要算法一样,都是不同长度的信息输入,产生固定长度的摘要输出。不同的是,它输出的信息摘要长度固定为256bits,即32字节。在实际使用过程中,SM3算法比较少会单独使用,而是配合SM2【非对称加密算法】配合使用,实现数字验签和消息验签的应用。
MAC(Message Authentication Code):消息认证码
MAC算法不同于以上3种信息摘要算法;MAC算法是带密钥的Hash函数:消息的散列值由只有通信双方才知道的秘密密钥K来控制。此时Hash值称作MAC。表达公式如下所示,其中M表示信息原文,P表示MAC算法,MAC表示输出的MAC值,K表示MAC密钥:
- P(M with any length) by K = MAC(with fixed length)
通过公式我们可以发现,计算MAC通常会有KEY的参与,那么在信息安全通讯领域,接收方要想验证收到的数据是否正确,就需要利用以上公式,输入MAC密钥重新计算一遍MAC值,然后对比计算值和收到的MAC值;若相等才认为数据是合法。这里涉及到一个MAC KEY,发送方和接收方对相同的数据进行MAC运算,能得到相同MAC值的前提,除了两者需使用相同的MAC算法外,还需要保证两者的MAC KEY是一致的(通常计算MAC采用的是对称加密算法)。至于,在实际生产应用过程中,如何保证两者的MAC KEY是一致的,或者说MAC KEY是如果从一方传递到另一方的,这又是另一个话题,这种应用场景,在POS机与银行后台信息交互的安全性,就是利用MAC KEY的。
MAC算法是一个统称,它很多种实现,在POS行业,常用的MAC算法有CUP模式、EMV2000模式、或者自定义形式的MAC算法。MAC算法的核心是如何将输入数据分组,利用MAC KEY做一些XOR、移位、加密等操作,使得输入数据散列化,最后再利用MAC KEY执行加密操作(通常为对称加密)得到MAC值。
值得注意的是,虽然MAC算法有MAC KEY的参与,但是它计算过程依然是单向的,不可逆的,这也是为什么会把它归为【信息摘要算法】的主要原因。
常见信息摘要算法的对比 信息摘要算法 信息输入长度 摘要输出长度 密钥 安全性 MD5 * 128bits(16字节) 无 低,有被碰撞的可能性 SHA1 * 160bits(20字节) 无 低,有被碰撞的可能性 SHA224 * 224bits(28字节) 无 较高 SHA256 * 256bits(32字节) 无 高,推荐使用,最长使用 SHA384 * 384bits(48字节) 无 高,推荐使用 SHA512 * 512bits(64字节) 无 高,高安全性场景下推荐使用 SM3 * 256bits(32字节) 无 高,推荐使用 MAC算法 * 视不同的MAC算法而不同
有的是8字节,有的是16字节
有 高,除非密钥被破解 注:表中*表示输入长度为“任意值”;此处的任意值,通常也是有限制的,比如SHA256,*应小于2的64次方,而SHA512,*应小于2的128次方。
信息摘要算法的应用场景
信息摘要算法的应用场景只要有以下几种:
- 网络文件下载
前面也简单提到了,在网络文件下载的时候,通常会有附上对应下载文件的摘要值,常用的是MD5或SHA1值;这个主要目的是给下载者在下载完网络文件后,做最后的文件正确性和完整性的确认。如果计算出来的摘要值,与网站上的摘要不相等,我们应认为下载的文件是不可信任的,应当做删除处理。
- 数字签名和信息验签
在产生数学签名的过程中,通常会有一步是对输入数据原文做摘要运算,这样做的主要目的是将输入数据原文迷你化。由于经摘要算法处理后,信息摘要的长度都是一定的,所以在做签名运算的时候,只需要对信息摘要做签名运算,在一定程度上就是输入信息的原文做签名运算。输入数据签名后,发送方会将签名数据附在输入信息的尾部,一同发送给接收方。而在验签流程中,接收方收到发送方的信息原文和签名值,首先需要做的是根据双方协商的信息摘要算法,做同样的摘要运算,得到摘要值M',然后使用密钥对签名数据进行解密运算,得到发送方的摘要M;如果M' = M,则表示验签通过,接收的数据是可任性的。
关于数字签名的具体细节,后续会有更为详细的文章做更进一步的介绍,比如常见的签名算法是怎么工作的,等等。
- 安全报文传输
这种应用场景,主要是MAC算法的应用,最常见的就是POS与银行后台的报文传输。由于涉及到金融风险,所以在POS机与银联后台通讯的过程中,除了对个人账户的敏感信息(如卡号、卡密码)等做加密处理外,还需要对整一个通讯报文做MAC计算,在发送报文的时候,MAC值附在原始的密文后面以供接收方对接收的密文做MAC校验。至于为何要这样做,就是为了保证通讯报文的其他信息要素不能被篡改,比如消费的金额。试想下,如果你在超市消费了1.00元,但是由于报文被截取了,攻击者将报文中的消费金额篡改为100.00元;这种情况下,除非报文攻击者拿到了POS与银行后台通讯的MAC KEY,否则它计算出来的MAC值必定与银行后台计算的MAC值对不上,进而被银行后台当做非法报文,做丢弃处理。但如果银行后台没有MAC值校验这一步操作,那么对于消费者而言,就是明明消费了1.00元却被扣款100.00元;这个后果将变得不堪设想。
本文对常见的信息摘要算法进行一番总结,阅读了本文后,相信读者对信息摘要算法都有了更为清晰的认识,同时对各个摘要算法之间的区别也有一定的了解。文中提及的观点,难免有纰漏之处,还望有心的读者诚心提出改进意见,互相学习,互相进步。感谢。
更多相关内容 -
Python hashlib常见摘要算法详解
2020-12-23 05:50:21这篇文章主要介绍了Python hashlib常见摘要算法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等 ... -
Java消息摘要算法MAC实现与应用完整示例
2020-08-25 16:09:39主要介绍了Java消息摘要算法MAC实现与应用,结合完整实例形式分析了java消息摘要算法MAC的概念、原理、实现方法及相关操作注意事项,需要的朋友可以参考下 -
MAC算法之消息摘要算法HmacMD5的实现
2020-08-29 19:03:52主要介绍了MAC算法之消息摘要算法HmacMD5的实现的相关资料,这里提供实例,帮助大家学习理解这部分知识,需要的朋友可以参考下 -
Java加密 消息摘要算法SHA实现详解
2020-08-25 19:21:08主要介绍了Java加密 消息摘要算法SHA实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 -
Java实现MD5消息摘要算法
2020-08-30 16:47:36本篇文章主要介绍了Java实现MD5消息摘要算法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧 -
3. 加密算法与消息摘要算法.txt
2020-06-26 14:00:303. 加密算法与消息摘要算法.txt -
Java加密 消息摘要算法MAC实现详解
2020-08-25 19:21:55主要介绍了Java 消息摘要算法MAC实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 -
搜索引擎动态摘要算法
2021-02-20 12:41:07搜索引擎摘要的选取原则、算法规则一直没有明确的框架或算法,以形成用户查询为中心的动态摘要为出发点,给出了动态摘要算法实现的形式化原则,并具体实现了一种动态摘要算法.与百度搜索引擎的动态摘要相比较,实验结果... -
Python和GO语言实现的消息摘要算法示例
2020-09-22 09:02:37主要介绍了Python和GO语言实现的消息摘要算法示例,本文讲解了python消息摘要示例、go语言消息摘要示例及各自的运行效果,需要的朋友可以参考下 -
常用几种消息摘要算法
2019-10-24 11:57:01文章目录1、`MD5 (Message Digest algorithm 5 消息摘要算法版本5)`2、`SHA (Secure Hash Algorithm 安全散列算法)`3、`MAC (Hash Message Authentication Code 散列消息鉴别码)` 消息摘要(Message Digest)又称为...文章目录
消息摘要(Message Digest)又称为数字摘要(Digital Digest)。它是一个唯一对应一个消息或文本的固定长度的值,它由一个单向Hash加密函数对消息进行作用而产生。如果消息在途中改变了,则接收者通过对收到消息的新产生的摘要与原摘要比较,就可知道消息是否被改变了。因此消息摘要保证了消息的完整性。
消息摘要采用单向Hash函数将需加密的明文"摘要"成一串固定位数(如128bit)的密文,这一串密文亦称为数字指纹(Finger Print),它有固定的长度,且不同的明文摘要成密文,其结果总是不同的,而同样的明文其摘要必定一致。这样这串摘要便可成为验证明文是否是“真身”的“指纹”了。
消息摘要具有不可逆性,在消息摘要生成过程中,会丢失很多原文的信息,而且无法找回。一个好的摘要算法,是极难产生Hash碰撞的,也就是找到另一段明文经计算后产生相同的摘要。
相关文章:
- https://www.cnblogs.com/yueshutong/p/11275420.html
- https://www.iteye.com/blog/snowolf-379860
有以下几种:
1、
MD5 (Message Digest algorithm 5 消息摘要算法版本5)
MD是应用非常广泛的一个算法家族,尤其是 MD5(Message-Digest Algorithm 5,消息摘要算法版本5),它由MD2、MD3、MD4发展而来,由Ron Rivest(RSA公司)在1992年提出,目前被广泛应用于数据完整性校验、数据(消息)摘要、数据加密等。MD2、MD4、MD5 都产生16字节(128位)的校验值,一般用32位十六进制数表示。MD2的算法较慢但相对安全,MD4速度很快,但安全性下降,MD5比MD4更安全、速度更快。
目前在互联网上进行大文件传输时,都要得用MD5算法产生一个与文件匹配的、存储MD5值的文本文件(后缀名为 .md5或.md5sum),这样接收者在接收到文件后,就可以利用与 SFV 类似的方法来检查文件完整性,目前绝大多数大型软件公司或开源组织都是以这种方式来校验数据完整性,而且部分操作系统也使用此算法来对用户密码进行加密,另外,它也是目前计算机犯罪中数据取证的最常用算法。与MD5 相关的工具有很多,如 WinMD5等。
案例实现:
/** * MD5 测试 * <br/> * 参考:https://www.jianshu.com/p/be000cf837b2 */ class Md5Test { public static void main(String[] args) throws NoSuchAlgorithmException { /* 得注意加密后字符串的大小写 */ // 待加密字符 String originalStr = "111111"; System.out.println(String.format("待加密字符: %s", originalStr)); // 已加密字符 String alreadyDigestStr = "96E79218965EB72C92A549DD5A330112"; System.out.println(String.format("已加密字符: %s", alreadyDigestStr)); /* jdk 实现 */ System.out.println("--------------jdk 实现-----------------"); // 获取信息摘要对象 MessageDigest md5 = MessageDigest.getInstance("MD5"); // 完成摘要 byte[] digest = md5.digest(originalStr.getBytes()); // 将摘要转换成 16 进制字符 (大写) String javaMd5Str = DatatypeConverter.printHexBinary(digest); System.out.println(String.format("%s 加密结果:%s", originalStr, javaMd5Str)); // 匹配验证 System.out.println(String.format("验证结果:%b", Objects.equals(javaMd5Str, alreadyDigestStr))); /* Apache commons-codec 实现 */ System.out.println("---------------Apache commons-codec 实现------------"); // 小写 String apacheMd5Str = DigestUtils.md5Hex(originalStr.getBytes()).toUpperCase(); System.out.println(String.format("%s 加密结果:%s", originalStr, apacheMd5Str)); System.out.println(String.format("验证结果:%b", Objects.equals(apacheMd5Str, alreadyDigestStr))); /* spring提供 */ System.out.println("-----------spring提供-----------"); // 小写 String springMd5Str = org.springframework.util.DigestUtils.md5DigestAsHex(originalStr.getBytes()).toUpperCase(); System.out.println(String.format("%s 加密结果:%s", originalStr, springMd5Str)); System.out.println(String.format("验证结果:%b", Objects.equals(springMd5Str, alreadyDigestStr))); } }
运行效果如下:
MD算法可用于密码保护。在用户注册时,利用MD算法取密码的摘要值,存入数据库。在用户登录时,将用户密码再次消息摘要后,与数据库密码进行比较即可得出用户登录结果。流程图如下:
MD5加密,是属于不可逆的。我们知道正常使用MD5加密技术,同一字符,加密后的16进制数是不变的,自从出现彩虹表,对于公司内部员工来说,可以反查数据,获取不可能的权限,所以出现了salt算法。
md5加盐算法,代码如下:
package com.blog.www.util.coder; import org.apache.commons.codec.digest.DigestUtils; import java.util.Objects; import java.util.Random; /** * MD5 加随机盐加密 * <br/> * 参考: <a href='https://www.cnblogs.com/peaceliu/p/7825706.html'>MD5加密+加盐</a> * <br/> * 基于:{@link DigestUtils} * <p> * 创建人:leigq <br> * 创建时间:2018-12-04 15:42 <br> * <p> * 修改人: <br> * 修改时间: <br> * 修改备注: <br> * </p> */ public class MD5WithSalt { /** * 生成含有随机盐的加密字符串 * <br>创建人: leigq * <br>创建时间: 2018-12-04 15:35 * <br> * * @param data 待加密的字符 * @return 加密后的字符(含 16 位随机盐),大写 */ public static String encrypt(String data) { Random r = new Random(); StringBuilder sb = new StringBuilder(16); sb.append(r.nextInt(99999999)) .append(r.nextInt(99999999)); int len = sb.length(); if (len < 16) { for (int i = 0; i < 16 - len; i++) { sb.append("0"); } } String salt = sb.toString(); String md5WithSaltStr = DigestUtils.md5Hex(data + salt); char[] cs = new char[48]; for (int i = 0; i < 48; i += 3) { cs[i] = md5WithSaltStr.charAt(i / 3 * 2); char c = salt.charAt(i / 3); cs[i + 1] = c; cs[i + 2] = md5WithSaltStr.charAt(i / 3 * 2 + 1); } return new String(cs).toUpperCase(); } /** * 校验密码是否正确 * <br>创建人: leigq * <br>创建时间: 2018-12-04 15:38 * <br> * * @param data 待验证的字符(明文) * @param md5StrContainRandomSalt 加密后的字符(含 16 位随机盐) * @return 验证结果 */ public static boolean verify(String data, String md5StrContainRandomSalt) { // 32 位加密字符(不含盐) char[] cs1 = new char[32]; // 16 位的随机盐 char[] cs2 = new char[16]; for (int i = 0; i < 48; i += 3) { cs1[i / 3 * 2] = md5StrContainRandomSalt.charAt(i); cs1[i / 3 * 2 + 1] = md5StrContainRandomSalt.charAt(i + 2); cs2[i / 3] = md5StrContainRandomSalt.charAt(i + 1); } String salt = new String(cs2); return Objects.equals(DigestUtils.md5Hex(data + salt).toUpperCase(), new String(cs1)); } }
测试:
/** * md5 加随机盐测试 */ class MD5WithSaltTest { public static void main(String[] args) { // 待加密字符 String originalStr = "111111"; // 已加盐加密字符 String md5WithSaltStr = MD5WithSalt.encrypt(originalStr); System.out.println(String.format("%s 加密结果:%s", originalStr, md5WithSaltStr)); // 不能直接再次加密验证,因为使用了随机盐,每次加密出来的字符串都不同 boolean verifyResult = MD5WithSalt.verify(originalStr, md5WithSaltStr); System.out.println(String.format("验证结果:%b", verifyResult)); } }
测试结果如下:
2、
SHA (Secure Hash Algorithm 安全散列算法)
SHA(Secure Hash Algorithm)是由美国专门制定密码算法的标准机构——美国国家标准技术研究院(NIST)制定的,SHA系列算法的摘要长度分别为:SHA-1为20字节(160位)、SHA-224为32字节(224位)、SHA-256为32字节(256位)、SHA-384为48字节(384位)、SHA-512为64字节(512位),由于它产生的数据摘要的长度更长,因此更难以发生碰撞,因此较之MD5更为安全,它是未来数据摘要算法的发展方向。由于SHA系列算法的数据摘要长度较长,因此其运算速度与MD5相比,也相对较慢。
目前SHA1的应用较为广泛,主要应用于CA和数字证书中,另外在目前互联网中流行的BT软件中,也是使用SHA1来进行文件校验的。
代码实现:
/** * SHA 加密算法测试 */ class SHATest { public static void main(String[] args) throws NoSuchAlgorithmException { // 待加密字符 String originalStr = "111111"; System.out.println(String.format("待加密字符: %s", originalStr)); // 已加密字符 String alreadyDigestStr = "3D4F2BF07DC1BE38B20CD6E46949A1071F9D0E3D"; System.out.println(String.format("已加密字符: %s", alreadyDigestStr)); /* jdk 实现 */ // 获取信息摘要对象 (SHA1),另外还有 SHA-224、SHA-256、SHA-384、SHA-512 MessageDigest md5 = MessageDigest.getInstance("SHA"); // 完成摘要 byte[] digest = md5.digest(originalStr.getBytes()); // 将摘要转换成 16 进制字符 (大写) String javaShaStr = DatatypeConverter.printHexBinary(digest); System.out.println(String.format("%s 加密结果:%s", originalStr, javaShaStr)); // 匹配验证 System.out.println(String.format("验证结果:%b", Objects.equals(javaShaStr, alreadyDigestStr))); /* Apache commons-codec 实现 */ String apacheShaStr = DigestUtils.sha1Hex(originalStr.getBytes()).toUpperCase(); System.out.println(String.format("%s 加密结果:%s", originalStr, apacheShaStr)); System.out.println(String.format("验证结果:%b", Objects.equals(apacheShaStr, alreadyDigestStr))); /* SHA256 */ System.out.println(DigestUtils.sha256Hex(originalStr.getBytes())); /* SHA384 */ System.out.println(DigestUtils.sha384Hex(originalStr.getBytes())); /* SHA512 */ System.out.println(DigestUtils.sha512Hex(originalStr.getBytes())); } }
运行结果如下:
消息鉴别:
3、
MAC (Hash Message Authentication Code 散列消息鉴别码)
MAC算法 (Message Authentication Codes消息认证码算法) 含有密钥的散列函数算法,兼容了MD和SHA算法的特性,并在此基础上加上了密钥。因此MAC算法也经常被称作HMAC算法。消息的散列值由只有通信双方知道的密钥来控制。此时Hash值称作MAC。
经过MAC算法得到的摘要值也可以使用十六进制编码表示,其摘要值得长度与实现算法的摘要值长度相同。例如 HmacSHA算法得到的摘要长度就是SHA1算法得到的摘要长度,都是160位二进制数,换算成十六进制的编码为40位。
流程分析:
甲乙双方进行数据交换可以采取如下流程:
1.甲方向乙方公布摘要算法(就是指定要使用的摘要算法名)
2.甲乙双方按照约定构造密钥,双方拥有相同的密钥(一般是一方构造密钥后通知另外一方,此过程不需要通过程序实现,就是双方约定个字符串,但是这个字符串可不是随便设定的,也是通过相关算法获取的)
3.甲方使用密钥对消息做摘要处理,然后将消息和生成的摘要消息一同发送给乙方
4.乙方收到消息后,使用甲方已经公布的摘要算法+约定好的密钥 对收到的消息进行摘要处理。然后比对自己的摘要消息和甲方发过来的摘要消息。甄别消息是否是甲方发送过来的。
代码实现:
/** * MAC 算法测试 */ class MacTest { public static void main(String[] args) throws NoSuchAlgorithmException, DecoderException, InvalidKeyException { // 待加密字符 String originalStr = "111111"; System.out.println(String.format("待加密字符: %s", originalStr)); // 已加密字符 String alreadyDigestStr = "74B31DBA9E16CCF752B294A18271BC6A"; System.out.println(String.format("已加密字符: %s", alreadyDigestStr)); /* jdk 实现 */ // 初始化 KeyGenerator, jdk 提供 HmacMD5、HmacSHA1、HmacSHA256、HmacSHA384和 HmacSHA512 四种算法 // KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5"); // 产生密钥 // SecretKey secretKey = keyGenerator.generateKey(); // 默认密钥 // byte[] defaultKey = secretKey.getEncoded(); // 自定义密钥 byte[] myKey = Hex.decodeHex(new char[]{'a','a','a','a','a','a','a','a','a','a'}); // 还原密钥 SecretKey restoreSecretKey = new SecretKeySpec(myKey, "HmacMD5"); // 实例化 MAC Mac mac = Mac.getInstance(restoreSecretKey.getAlgorithm()); // 初始化 MAC mac.init(restoreSecretKey); //执行摘要 byte[] hmacMD5Bytes = mac.doFinal(originalStr.getBytes()); String encodeHexString = Hex.encodeHexString(hmacMD5Bytes).toUpperCase(); System.out.println(String.format("%s 加密结果:%s", originalStr, encodeHexString)); System.out.println(String.format("验证结果:%b", Objects.equals(encodeHexString, alreadyDigestStr))); /* apache 实现 */ // HmacMD5 HmacUtils hmacMd5 = new HmacUtils(HmacAlgorithms.HMAC_MD5, myKey); String apacheHmacMd5 = hmacMd5.hmacHex(originalStr.getBytes()).toUpperCase(); System.out.println(String.format("%s 加密结果:%s", originalStr, apacheHmacMd5)); System.out.println(String.format("验证结果:%b", Objects.equals(apacheHmacMd5, alreadyDigestStr))); // HmacSHA1 HmacUtils hmacSha1 = new HmacUtils(HmacAlgorithms.HMAC_SHA_1, KeyGenerator.getInstance(HmacAlgorithms.HMAC_SHA_1.getName()).generateKey().getEncoded()); String apacheHmacHex1 = hmacSha1.hmacHex(originalStr.getBytes()).toUpperCase(); System.out.println(String.format("%s 加密结果:%s", originalStr, apacheHmacHex1)); // HmacSHA256 HmacUtils hmacSha256 = new HmacUtils(HmacAlgorithms.HMAC_SHA_256, KeyGenerator.getInstance(HmacAlgorithms.HMAC_SHA_256.getName()).generateKey().getEncoded()); String apacheHmacSha256 = hmacSha256.hmacHex(originalStr.getBytes()).toUpperCase(); System.out.println(String.format("%s 加密结果:%s", originalStr, apacheHmacSha256)); // HmacSHA384 , 类似上面 // HmacSHA512, 类似上面 } }
运行结果:
上面这几种摘要算法,可谓是非可逆加密,就是不可解密的加密方法。我们通常只把他们作为加密的基础。单纯的以上三种的加密并不可靠。
-
最新消息摘要算法
2014-06-08 10:08:11NIST选出的最新消息摘要算法,用于提到SHA1和SHA2. -
SHA1摘要算法-C语言
2020-11-22 16:33:37C语言实现SHA1摘要算法。编译环境:VS2010。请参考我的博客https://blog.csdn.net/u013073067/article/details/86597385 分析代码 -
消息摘要算法概述及简介
2019-06-03 13:04:29如果消息在传递的途中改变了,接收者通过对收到消息采用相同的Hash重新计算,新产生的摘要与原摘要进行比较,就可知道消息是否被篡改了,因此消息摘要能够验证消息的完整性。消息摘要采用单向Hash函数将需要计算的...概述
数字摘要也称为消息摘要,它是一个唯一对应一个消息或文本的固定长度的值,它由一个单向Hash函数对消息进行计算而产生。如果消息在传递的途中改变了,接收者通过对收到消息采用相同的Hash重新计算,新产生的摘要与原摘要进行比较,就可知道消息是否被篡改了,因此消息摘要能够验证消息的完整性。消息摘要采用单向Hash函数将需要计算的内容"摘要"成固定长度的串,这个串亦称为数字指纹。这个串有固定的长度,且不同的明文摘要成密文,其结果总是不同的(相对的),而同样的明文其摘要必定一致。这样这串摘要便可成为验证明文是否是"真身"的"指纹"了。
消息摘要算法:
MD(Message Digest)
SHA(Secure Hash Algorithm)
MAC(Message Authentication Code)
用于验证数据完整性(登录注册、文件校验),登录注册模型分析如下图消息摘要算法专门用于验证数据完整性,它源于CRC冗余校验算法,派生出MD和SHA两大系列消息算法,在此基础上又衍生出MAC算法。消息摘要算法是数字签名算法的基础。
几乎每种消息摘要算法都大概三种实现方式:Sun、Bouncy Castle和Commons Codes。Sun提供了最基本的算法实现;Bouncy Castle是在Sun基础上做了扩展,实现了Sun未提供的算法;Commons Codes在Sun基础上,对方法做封装,提高易用性。MD算法家族有MD2、MD4、MD5三种算法,在Java 6中通过MessageDigest类提供MD2和MD5两种算法支持;通过Bouncy Castle扩展,可提供MD4算法支持;Commons Codes则直接提高了MD5算法使用的便利性。
MD、SHA、MAC都是加密算法领域的消息摘要算法,与之功能相近的CRC-32则是较古老、用于通信领域实现差错控制的数据完整性验证算法。
1、MD5MD家族(MD2、4、5)128位摘要信息
2、SHA模型
应用
1、加入约定Key
2、增加时间戳
3、排序msg:原始消息+key+时间戳
3、MAC
- MAC(Message Authentication Code)
-
HMAC(keyed-Hash Message Authentication Code),含有密钥的散列算法
-
融合MH、SHA
- MD系列:
- SHA系列:HmacSHA1、HmacSHA224、HmacSHA256、HmacSHA384、HmacSHA512
模型:
应用:如SecureCRT(linux远程工具)
-
MD消息摘要算法实现及改进.doc
2022-03-19 18:19:37MD消息摘要算法实现及改进.doc -
MD5消息摘要算法
2018-05-24 17:57:02MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护。 -
消息摘要(Message Digest)及其算法
2020-02-05 17:46:20这看上去有悖摘要算法的原理,不是压缩计算?不是不可逆吗? 为什么可以得到原文呢?看一下该网站的介绍稍稍安心了。该网站通过反向查询的方法获取结果,存储了大量的原文和摘要的对应。但是不管怎样, MD5等都不是...文章目录
此篇是对
Java之消息摘要(MD5)的深入与补充。消息摘要(Message Digest,MD)
摘要的意思是摘录的要点,文章的摘要是指的是该文章的内容提要。信息领域的消息摘要是对一个数据块的数字指纹。
这里对一段消息的摘要不是该消息的内容提要,而是该消息的数字指纹,是一串固定长度的字符串。消息摘要具有以下属性:- 消息改变, 摘要必然不一样
- 不能伪造相同摘要的不同消息。
消息摘要最著名的算法就是SHA1和MD5。建议使用SHA1。
消息摘要是数据块的指纹, 在签署合同时,签署双方按上指纹以确定合同的有效性,如果双方签署下一个合同,按的指纹是一样的。而不同的合同产生出来的消息摘要是不一样的,除非两份合同完全一致。
哈希(Hash)及算法
Hash概念及特点
Hash,直译是“哈希”,更常见的翻译是“散列”,也有翻译为“杂凑”。其定义是将任意长度的输入通过散列算法换成固定长度的输出,这个输出就是散列值。
以数学中求模算法为例: 9%2的结果是1, 19%2的结果也是1,但哈希算法远比这复杂。其输入可以是字符串、文本或是文件,其输出是固定长度的哈希值。
Hash函数分类
Hash算法,也称Hash函数或散列函数。哈希算法将数据打乱混合,创建一个唯一的哈希值。
Hash函数是一种单向的加密体制,将任意长度的输入经过转换得到固定长度的输出,但这个过程不可逆,只有加密过程,没有解密过程。常见的哈希函数分类有:- 加法Hash: 利用加法构造。
- 位运算 Hash: 利用移位或异或来混合输入元素。
- 乘法Hash
- 除法Hash
- 查表Hash
- 混合Hash:混合以上的方式,比如MD5等
Hash碰撞(Collision)
不同的输入使用Hash函数获取的Hash值如果相同,则称发生了碰撞。也就是不同的消息,产生相同的消息摘要。
对于简单的加法或是乘法函数,出现碰撞的可能性很大;对于MD5等算法,虽然概率非常小,但是在理论和现实中都是存在的,这样的算法也就是不安全的了。
好的Hash函数(f)应当满足以下3个条件:- 不能从应变量得到自变量。也就是f(x)=y函数,对于任意的y, 不能找到x。
- 弱无碰撞性。给定x1∈A,找x2∈B,,使得f(x1)=f(x2),在计算上是不可能的
- 强无碰撞性,寻找x1,x2,使得f(x1)=f(x2),在计算上也是不可行的。
碰撞的处理方法有两类: 开放寻址法(Open Addressing)和链接法(Chaining)。
Hash算法
常见的Hash算法有:MD(Message Digest,消息摘要)、SHA(Secure Hash Algorithm,安全摘要)和MAC(Message Authentication Code,消息认证码)。
MD5和SHA1应该是目前适用最为广泛的Hash算法,这两个算法是在MD4基础上产生。-
MD4, MD是Message Digest的简写,由MIT(麻省理工)在1990年设计,是基于32位系统实现。输出128位。
-
MD5, 1991年MD4改进。相比MD4,速度稍慢,但更安全。
MD5以512位分组来处理输入信息,每一分组会分为16个32bit子分组,经过算法处理后,最终输出有4个32位分组组成,将这4个32位分组级联组成 128位散列值。 -
SHA-1,输出160位。
-
SHA-2,包括SHA-224、SHA-256、SHA-384、SHA-512,后面是输出的位数。
-
MAC,带密钥的Hash函数。
MD5和SHA函数都只有一个输入参数:消息。 如果增加一个密钥(key)的参数,则会生成一个加密的消息摘要。
Hash算法比较
信息摘要越长,发生碰撞的几率就越低,破解难度就越大,但同时,耗费的性能和占用的空间就越高。
这里主要比较MD5和SHA-1的差异。
MD5摘要长度128bit,SHA-1摘要长度160bit,SHA-1比MD5多出了32bit,也就是对原文的碰撞几率降低了2^32 = 324294967296倍,但SHA-1比MD5性能略低。
摘要最终的。
在https://www.cmd5.com/ 可以查到使用不同摘要算法产生的字符串。
应用
消息摘要可以用来加密字串和验证内容是否被篡改,依据此特性,实际的应用包括:
-
数据完整性检查(Data Integrity Check)
用作SSL/TLS/IPsec, 原始数据生成消息摘要,共享对称密钥加密,接收方逆操作 -
数字证书签名(Digital Certification Signature)
将服务器的数字证书生成消息摘要,用CA的私钥加密,这个MD就变成了CA的数字签名,附在原始证书的末尾,作为CA签名的数字证书
服务端与客户端认证时,将CA签名证书发给客户端,客户端拥有CA的公钥(手动或浏览器安装),可以解密CA的数字签名,得到消息摘要。然后客户端自身使用Hash算法运算数字证书,比较两个消息摘要是否一致,一致则认证通过。 -
数据校验(Checksum),验证软件没有被篡改。
将原始文件生成MD5 Checksum,用户下载完文件,计算下载文件的MD5 Checksum,如果相同,则文件完好。
以JDK 8的下载为例,在https://www.oracle.com/webfolder/s/digest/8u241checksum.html可以看到安装文件的Checksum。界面如下:
-
数据来源可靠性认证
-
密码加密, 密码通过Hash算法(比如MD5)加密后存入数据库,即使被截取了,也无法得到原密码。
MD5等算法的安全性
在实际应用中,MD5产生的消息摘要除了用来验证数据的完整性,也常被用来对密码加密。在很多应用中,用户的密码都会被MD5加密后存入数据库。但密码丢失时,一般就只能重置密码而无法找回。这看上去很完美。但2004年的国家密码学年会上,山东大学王小云教授的"破译md5、haval-128、md4以及ripemd-128算法"的报告,实现了MD5的破译。更神奇的还是来看 http://www.cmd5.com/ 这个网站。
在密文输入消息摘要,点“查询”之后就可以看到原文了。
这看上去有悖摘要算法的原理,不是压缩计算?不是不可逆吗? 为什么可以得到原文呢?看一下该网站的介绍稍稍安心了。该网站通过反向查询的方法获取结果,存储了大量的原文和摘要的对应。但是不管怎样, MD5等都不是很安全了。哈希表(HashMap,Hash Table)
在Java等语言中, HashMap是一种常用的数据结构,以键值对的方式存储和访问数据的格式,优势是查找数据较快。
哈希表,也成为散列表,是基于快速存储的角度而设计,该数据结构可以理解为一个线性表,但其中的元素不是紧密排列的。
把键映射到表中位置的函数就是映射函数。
在HashMap中的较好的散列函数是使数据元素更快的被定位,常见的方法有:- 直接寻址, 去关键字或关键子的某个线性函数为散列地址。 表达式为:
H(key)=key 或 H(key)=akey+b
比如: 以公司员工的出生年月日为键。 - 数字分析法。 找出数字的规律,尽可能利用这些数据构造冲突几率较低的散列地址。
沿用上面的示例,出生年月日有很大的可能性出现冲突。这时候可以分析数据,找到合适的键。 - 平方取中法。取关键字平方后的中间几位作为散列地址。
- 折叠法。将关键字分割成位数相同的几部分,最后一部分位数可以不同,然后取这及部分的叠加和作为散列地址。
- 随机数法。 选择一随机函数,取关键字的随机值作为散列地址,通常适用于关键子长度不同的场合。
- 除留余数法。取关键子被某个不大于散列表长m的数p除后所得的余数为散列地址。
哈希表、数组和链表
- 数组是元素的有序序列,在内存中也是按照这个先后顺序连续存放在一起。在Java中的整型数组 int a[10]。
- 链表是物理上非连续、非顺序的存储结构,数据元素的逻辑顺序通过链表中的指针链接次序实现。
简单数据结构如下:
数组寻址容易,也就是查找容易,但插入和删除难; 链表寻址困难,但插入和删除容易。如果将数组和链表组合在一起,就可以发挥两者的优势。
如何根据数组的特征计算下标就要使用哈希算法了。哈希算法根据Key来定位其在HashMap中的位置。
在JDK 8中,通过hashCode()的高16位异或低16位实现的:(h = k.hashCode()) ^ (h >>> 16),主要是从速度、功效、质量来考虑的。以上方法得到的int的hash值,然后再通过h & (table.length -1)来得到该对象在数据中保存的位置。
-
Java加密算法:消息摘要算法、对称加密算法代码及总结
2016-05-23 17:59:12包含消息摘要算法和对称加密算法的代码及应用总结 -
消息摘要函数 SHA-1 算法的 数据填充和扩展
2021-08-13 11:10:04消息摘要函数 SHA-1 算法的 数据填充和扩展 -
Java加密算法—消息摘要及文件消息摘要
2022-02-15 13:30:56Java加密算法—消息摘要及文件消息摘要 -
消息摘要算法
2019-04-11 20:37:47定义: 消息摘要算法又称为散列算法,其核心在于散列函数的...消息摘要算法主要分为三大类:MD(Message Digest,消息摘要算法)、SHA(Secure Hash Algorithm,安全散列算法)和MAC(Message Authentication Code,消息认... -
java加密算法:Base64加密\数字签名\对称加密算法\非对称加密算法\消息摘要算法
2015-03-15 21:52:20java关于加密的算法demo代码(Base64加密\数字签名\对称加密算法\非对称加密算法\消息摘要算法) JAVA安全实现三种方式: 1.JDK 2.Commons Codec 3.Bouncy Castle 一。非对称加密算法: 1.DH 2.RSA 3.ELGamal 二。... -
摘要算法和加密算法
2022-04-01 14:04:16概要算法和加密算法的讲解与比较 -
三种摘要算法的简单介绍
2018-03-19 10:36:26原文地址:http://blog.csdn.net/u013991521/article/details/48193953介绍:消息摘要算法分为三类:MD(Message Digest):消息摘要SHA(Secure Hash Algorithm):...验证数据的完整性消息摘要算法是有关于数字签名... -
MD5 摘要算法应用详解
2020-06-23 23:37:32MD5是典型的消息摘要算法,是广泛使用的消息摘要算法之一,更是消息摘要算法首要代表。其前身包括MD2、MD4。MD算法家族针对源数据会产生一个128位的消息摘要。在一般应用场景下,会将128二进制摘要信息转换为... -
算法设计摘要
2018-05-08 22:48:28算法设计摘要算法设计摘要算法设计摘要算法设计摘要算法设计摘要算法设计摘要 -
常用的消息摘要算法
2017-08-24 10:18:23常用的消息摘要算法 -
国密SM3摘要算法工具
2013-11-14 11:20:51按照国密SM3算法实现手册,VC++ MFC编译实现的摘要工具。欢迎大家试用