首页 > 编程知识 正文

如何攻击单向散列函数,单向散列函数加密算法

时间:2023-05-06 18:51:52 阅读:170566 作者:739

微信搜索:旋风StayUp

主页地址: https://gozhuyinglong.github.io

共享源代码: https://github.com/gozhuyinglong/blog-demos

1 .定义http://www.Sina.com/(one-wayhashfunction )是指对不同的输入值用单向散列函数进行计算,得到固定长度的输出值。 此输入值称为单向散列函数(message,输出值称为消息(hash value )。

单向散列函数还可被称为http://www.Sina.com/(messagedigestfunction )、散列值消息摘要函数。 输入的消息也称为http://www.Sina.com/(pre-image )。 输出的哈希值也称为http://www.Sina.com/(消息digest )或哈希函数(fingerprint ),相当于此消息的身份证。

单向散列函数有各种各样的实现算法,常见的有杂凑函数原像消息摘要,http://ww.Sina.com /,http://ww.Sina

2 .由于特性上的定义,关于单向散列函数的理解是模糊的。 介绍单向散列函数的特性,加深一下印象吧。

2.1哈希值的长度不管固定消息的长度如何,使用相同算法计算的哈希值的长度总是固定的。 例如,在MD5算法中,不管怎么输入,所生成的散列值的长度总是128位(16字节)。

但是,位是计算机可以识别的单位,我们人类习惯用十六进制字符串来表示(一个字节占用两位十六进制字符)。

2.2如果使用相同的消息,不同的消息具有不同的散列值,则生成的散列值一定相同。

生成的哈希值因消息而异。 即使只有1比特的差异,得到的散列值也有很大的差异。

该特性也称为指纹,不应该用于抗冲突的算法。

2.3具有单向性,只能根据消息计算出哈希值,不能根据哈希值反算消息。

2.4计算速度快哈希值的计算速度快。 消息越长,计算哈希值的时间也越长,但可以在短时间内完成。

3 .常见算法MD5和SHA-1算法取得突破,不应用于新用途; SHA-2和SHA-3仍然安全,可以使用。

SHA-2包括SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224和SHA-512/256。

SHA-3包括SHA3-224、SHA3-256、SHA3-384和SHA3-512。

算法名称哈希值长度是否安全MD5128不安全SHA-1160不安全SHA-224224安全SHA-256256安全SHA-384384安全SHA-512512安全SHA-512/224224安全SHA-512/256256安全SHA3-224224安全SHA3-256256安全SHA3-384384安全SHA3-512512安全4 .应用场景单向散列函数不能保证信息的机密性,是一种保证信息完整性的加密技术。 让我们看看它的应用场景。

4.1用户密码保护用户在设置密码时,不记录密码本身,只记录密码的哈希值,只有用户自己知道密码的明文。 检查密码时,如果输入的密码正确,则得到的散列值一定相同,这表明检查是正确的。

为了防止破坏彩虹列表,还可以对密码进行盐处理。 验证密码时,使用同样的盐就可以完成检查。

使用哈希值存储密码的好处是,即使数据库被盗,也无法将密文反过来挤出什么是明文,从而使密码的存储更加安全。

4.2接口验证签名为保证接口安全,可以采用签名方式发送。

发件人和收件人在MD5发件人向收件人发送请求时,在参数上签名(签名是用SHA-1业务参数,通过单向散列函数加密生成的)。 接收者在收到后,用同样的方法生成签名,与收到的签名进行核对,如果一致则验证成功。

这样,能够验证业务参数是否被篡改,确认发送者的身份。

4.3文件完整性检查文件挂载在网站上时,还附上其哈希值和算法,例如Tomcat官方网站。

下载后,用户通过计算哈希值并比较结果是否相同来验证文件的完整性。

4.4云盘秒传我们把喜欢的视频放到网盘上的时候,几秒钟就上传成功了,这个文件有几个GB大小。 它是怎么做的呢?

其实这个“秒传”功能可以利用单向散列函数来实现。

上载文件时,基于云的客户端首先为该文件生成哈希值。 带着这个哈希值去数据

库中匹配,如果匹配到,说明该文件已经在云服务器存在。只需将该散列值与用户进行关联,便可完成本次“上传”。

这样,一个文件在云服务器上只会存一份,大大节约了云服务器的空间。

5. 代码实现

JDK的 java.security.MessageDigest 类为我们提供了消息摘要算法,用于 MD5和SHA的散列值生成。下面代码做了简单的封装,便于直接使用。

public class MDUtil { /** * MD5 加密 * * @param data 要加密的数据 * @return 32位十六进制字符串 */ public static String MD5(byte[] data) { try { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] bytes = md.digest(data); return bytesToHexString(bytes); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; } /** * MD5 加密 * * @param data 要加密的数据 * @return 32位十六进制字符串 */ public static String MD5(String data) { return MD5(data.getBytes()); } /** * SHA-1 加密 * * @param data 要加密的数据 * @return 40位十六进制字符串 */ public static String SHA1(byte[] data) { try { MessageDigest md = MessageDigest.getInstance("SHA-1"); byte[] bytes = md.digest(data); return bytesToHexString(bytes); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; } /** * SHA-1 加密 * * @param data 要加密的数据 * @return 40位十六进制字符串 */ public static String SHA1(String data) { return SHA1(data.getBytes()); } /** * SHA-224 加密 * * @param data 要加密的数据 * @return 56位十六进制字符串 */ public static String SHA224(byte[] data) { try { MessageDigest md = MessageDigest.getInstance("SHA-224"); byte[] bytes = md.digest(data); return bytesToHexString(bytes); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; } /** * SHA-224 加密 * * @param data 要加密的数据 * @return 56位十六进制字符串 */ public static String SHA224(String data) { return SHA224(data.getBytes()); } /** * SHA-256 加密 * * @param data 要加密的数据 * @return 64位十六进制字符串 */ public static String SHA256(byte[] data) { try { MessageDigest md = MessageDigest.getInstance("SHA-256"); byte[] bytes = md.digest(data); return bytesToHexString(bytes); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; } /** * SHA-256 加密 * * @param data 要加密的数据 * @return 64位十六进制字符串 */ public static String SHA256(String data) { return SHA256(data.getBytes()); } /** * SHA-384 加密 * * @param data 要加密的数据 * @return 96位十六进制字符串 */ public static String SHA384(byte[] data) { try { MessageDigest md = MessageDigest.getInstance("SHA-384"); byte[] bytes = md.digest(data); return bytesToHexString(bytes); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; } /** * SHA-384 加密 * * @param data 要加密的数据 * @return 96位十六进制字符串 */ public static String SHA384(String data) { return SHA384(data.getBytes()); } /** * SHA-512 加密 * * @param data 要加密的数据 * @return 128位十六进制字符串 */ public static String SHA512(byte[] data) { try { MessageDigest md = MessageDigest.getInstance("SHA-512"); byte[] bytes = md.digest(data); return bytesToHexString(bytes); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; } /** * SHA-512 加密 * * @param data 要加密的数据 * @return 128位十六进制字符串 */ public static String SHA512(String data) { return SHA512(data.getBytes()); } /** * 将字节数组转换为十六进制字符串 * * @param bytes 字节数组 * @return 十六进制字符串 */ private static String bytesToHexString(byte[] bytes) { StringBuilder hexValue = new StringBuilder(); for (byte b : bytes) { int val = b & 0xFF; if (val < 16) { hexValue.append("0"); } hexValue.append(Integer.toHexString(val)); } return hexValue.toString(); }}

下面分别使用这些算法计算“123456”的散列值:

public static void main(String[] args) { System.out.println("MD5tt" + MDUtil.MD5("123456")); System.out.println("SHA-1t" + MDUtil.SHA1("123456")); System.out.println("SHA-224t" + MDUtil.SHA224("123456")); System.out.println("SHA-256t" + MDUtil.SHA256("123456")); System.out.println("SHA-384t" + MDUtil.SHA384("123456")); System.out.println("SHA-512t" + MDUtil.SHA512("123456"));}

输出结果:

MD5 e10adc3949ba59abbe56e057f20f883eSHA-1 7c4a8d09ca3762af61e59520943dc26494f8941bSHA-224 f8cdb04495ded47615258f9dc6a3f4707fd2405434fefc3cbf4ef4e6SHA-256 8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92SHA-384 0a989ebc4a77b56a6e2bb7b19d995d185ce44090c13e2984b7ecc6d446d4b61ea9991b76a4c2f04b1b4d244841449454SHA-512 ba3253876aed6bc22d4a6ff53d8406c6ad864195ed144ab5c87621b6c233b548baeae6956df346ec8c17f5ea10f35ee3cbc514797ed7ddd3145464e2a0bab413

我用的是Java8,还不支持 SHA-3,所以上面代码只封装了MD5、SHA-1和SHA-2。

从Java9开始支持SHA-3

6. 完整代码

完整代码请访问我的Github,若对你有帮助,欢迎给个Star,谢谢!

https://github.com/gozhuyinglong/blog-demos/blob/main/java-source-analysis/src/main/java/io/github/gozhuyinglong/utils/MDUtil.java

7. 推荐阅读 散列表(哈希表)

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。