1. HASH算法

哈希算法(Hash)又称摘要算法(Digest),它的作用是:对任意一组输入数据进行计算,得到一个固定长度的输出摘要。

哈希函数的主要作用不是完成数据加密与解密工作,它是用来检验数据完整性的重要技术,运算结果具有不可逆性。

通过哈希函数,可以为数据创建"数组指纹"(散列值/哈希值),哈希值通常是一个短的随机字母和数字组成的字符串。消息认证流程如下:

在上述认证流程中,信息收发双方在通信前已经商定好了具体的哈希算法,并且该算法是公开的。

如果消息在传递过程中被篡改,则该消息不能与已经获得的数字指纹(哈希值)相匹配。


2. 哈希函数的一些特性:

  • 消息的长度不受限制;
  • 对于给定的消息,其哈希值的计算是很容易的;
  • 如果两个哈希值不想同,则这两个哈希值的原文数据也不想同,这个特性使得哈希函数具有确定性的结果;
  • 哈希函数的运算过程是不可逆的,即函数的单向性。这也是单向函数命名的由来。
  • 对于一个已知的消息和其哈希值,要找到另一个消息使其获得相同的哈希值是不可能的,即抗弱碰撞性,用来防止伪造。

哈希函数官方用于消息完整性验证,是数据签名的核心技术。

哈希函数的常用算法有:MD(消息摘要算法)、SHA(安全散列算法)及Mac(消息认证码算法)

算法 输出长度(位) 输出长度(字节)
SM3 256 bits 32 bytes
MD5 128 bits 16 bytes
SHA-1 160 bits 20 bytes
RipeMD-160 160 bits 20 bytes
SHA-256 256 bits 32 bytes
SHA-512 512 bits 64 bytes

3. 举个栗子

Java标准库提供了常用的哈希算法,并且有一套统一的接口。我们以MD5算法为例,看看如何对输入计算哈希:

@Testpublic void run2(){try {MessageDigest messageDigest = MessageDigest.getInstance("MD5");// 反复调用update输入数据:messageDigest.update("Hello".getBytes(StandardCharsets.UTF_8));messageDigest.update("World".getBytes(StandardCharsets.UTF_8));byte[] result = messageDigest.digest();System.out.println(new BigInteger(1, result).toString(16));} catch (NoSuchAlgorithmException e) {e.printStackTrace();}}

运算结果:

68e109f0f40ca72a15e05cc22786f8e6


4. 哈希算法的用途

因为相同的输入永远会得到相同的输出,因此,如果输入被修改了,得到的输出就会不同。

4.1 文件防篡改

我们在网站上下载软件的时候,经常看到下载页显示的哈希:

如何判断下载到本地的软件是原始的、未经篡改的文件?我们只需要自己计算一下本地文件的哈希值,再与官网公开的哈希值对比,如果相同,说明文件下载正确,否则,说明文件已被篡改。

4.2 彩虹表

哈希算法的另一个重要用途是存储用户口令。如果直接将用户的原始口令存放到数据库中,会产生极大的安全风险:

  • 数据库管理员能够看到用户明文口令;
  • 数据库数据一旦泄漏,黑客即可获取用户明文口令。

不存储用户的原始口令,那么如何对用户进行认证?

方法是存储用户口令的哈希,例如:MD5

在用户输入原始口令后,系统计算用户输入的原始口令的MD5并与数据库存储的MD5对比,如果一致,说明口令正确,否则,口令错误。

因此,数据库存储用户名和口令的表内容应该像下面这样:

username password
bob f30aa7a662c728b7407c54ae6bfd27d1
alice 25d55ad283aa400af464c76d713c07ad
tim bed128365216c019988915ed3add75fb

这样一来,数据库管理员看不到用户的原始口令。即使数据库泄漏,黑客也无法拿到用户的原始口令。想要拿到用户的原始口令,必须用暴力穷举的方法,一个口令一个口令地试,直到某个口令计算的MD5恰好等于指定值。

使用哈希口令时,还要注意防止彩虹表攻击

什么是彩虹表呢?上面讲到了,如果只拿到MD5,从MD5反推明文口令,只能使用暴力穷举的方法。

然而黑客并不笨,暴力穷举会消耗大量的算力和时间。但是,如果有一个预先计算好的常用口令和它们的MD5的对照表:

常用口令 MD5
hello123 f30aa7a662c728b7407c54ae6bfd27d1
12345678 25d55ad283aa400af464c76d713c07ad
passw0rd bed128365216c019988915ed3add75fb
19700101 570da6d5277a646f6552b8832012f5dc
20201231 6879c0ae9117b50074ce0a0d4c843060

这个表就是彩虹表

如果用户使用了常用口令,黑客从MD5一下就能反查到原始口令:

bob的MD5:f30aa7a662c728b7407c54ae6bfd27d1,原始口令:hello123

alice的MD5:25d55ad283aa400af464c76d713c07ad,原始口令:12345678

tim的MD5:bed128365216c019988915ed3add75fb,原始口令:passw0rd

这就是为什么不要使用常用密码,以及不要使用生日作为密码的原因。

4.3 如何抵御彩虹表攻击

即使用户使用了常用口令,我们也可以采取措施来抵御彩虹表攻击:方法是对每个口令额外添加随机数,这个方法称之为加盐(salt):

digest = md5(salt+inputPassword)

经过加盐处理的数据库表,内容如下:

username salt password
bob H1r0a a5022319ff4c56955e22a74abcc2c210
alice 7$p2w e5de688c99e961ed6e560b972dab8b6a
tim z5Sk9 1eee304b92dc0d105904e7ab58fd2f64

加盐的目的在于使黑客的彩虹表失效,即使用户使用常用口令,也无法从MD5反推原始口令。

SHA-1

SHA-1也是一种哈希算法,它的输出是160 bits,即20字节。SHA-1是由美国国家安全局开发的,SHA算法实际上是一个系列,包括SHA-0(已废弃)、SHA-1、SHA-256、SHA-512等。

在Java中使用SHA-1,和MD5完全一样,只需要把算法名称改为"SHA-1",类似的,计算SHA-256,我们需要传入名称"SHA-256",计算SHA-512,我们需要传入名称"SHA-512"

  • Java标准库支持的所有哈希算法可以在这里查到。 

MessageDigest Algorithms

Algorithm names that can be specified when generating an instance of MessageDigest.

Algorithm Name Description
MD2 The MD2 message digest algorithm as defined in RFC 1319.
MD5 The MD5 message digest algorithm as defined in RFC 1321.
SHA-1
SHA-224
SHA-256
SHA-384
SHA-512/224
SHA-512/256
Hash algorithms defined in FIPS PUB 180-4. Secure hash algorithms - SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, SHA-512/256 - for computing a condensed representation of electronic data (message). When a message is input to a hash algorithm, the result is an output called a message digest. A message digest ranges in length from 160-512 bits, depending on the algorithm.
SHA3-224
SHA3-256
SHA3-384
SHA3-512
Permutation-based hash and extendable-output functions as defined in FIPS PUB 202. An input message length can vary; the length of the output digest is fixed.

SHA3-224 produces a 224 bit digest.
SHA3-256 produces a 256 bit digest.
SHA3-384 produces a 384 bit digest.
SHA3-512 produces a 512 bit digest.

摘要算法(哈希算法)相关推荐

  1. C# MD5摘要算法、哈希算法

    MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致.是计算机广泛使用的杂凑算法之一(又译摘要算法.哈希算法) MD5算法具有以下特点: 1.压缩 ...

  2. python hashlib 哈希算法

    写在篇前 ​ 哈希加密算法应用非常广泛,包括数字签名,身份验证,操作检测,指纹,校验和(消息完整性检查),哈希表,密码存储等.在密码学中,好的哈希算法应该满足以下两个条件:一是无法从哈希值解密原始消息 ...

  3. 数据结构与算法之美-哈希算法

    哈希算法的定义和原理 将任意长度的二进制串映射为固定长度的二进制串. 这个映射的规则就是哈希算法,而通过原始数据映射之后得到的二进制串就是哈希值. 设计一个优秀的哈希算法需要满足: 从哈希值不能反向推 ...

  4. 群人各说什么是哈希算法?

    这个HASH算法不是大学里数据结构课里那个HASH表的算法.这里的HASH算法是密码学的基础,比较常用的有MD5和SHA,最重要的两条性质,就是不可逆和无冲突. 所谓不可逆,就是当你知道x的HASH值 ...

  5. 21 | 哈希算法(上):如何防止数据库中的用户信息被脱库?

    问题:对于用户信息中的密码,你会如何存储用户密码?仅仅 MD5 加密一下存储就够了吗?--哈希算法 什么是哈希算法 哈希算法的定义和原理:将任意长度的二进制值串映射为固定长度的二进制值串,这个映射的规 ...

  6. 【数据结构与算法】哈希算法

    一.什么是哈希算法? 1.定义 将任意长度的二进制值串映射成固定长度的二进制值串,这个映射的规则就是哈希算法,而通过原始数据映射之后得到的二进制值串就是哈希值. 2.如何设计一个优秀的哈希算法? ①单 ...

  7. 面试官:怎么改进哈希算法实现负载均衡的扩展性和容错性?我:...

    面试官:怎么改进哈希算法实现负载均衡的扩展性和容错性? 什么是哈希算法 数据结构中我们学习过哈希表也称为散列表,我们来回顾下散列表的定义. 散列表,是根据键直接访问在指定储存位置数据的数据结构.通过计 ...

  8. 图解一致性哈希算法,看这文就够了!

    作者 | LemonCoder 来源 | 后端技术学堂(ID:lemon10240) 很多同学应该都知道什么是哈希函数,在后端面试和开发中会遇到「一致性哈希」,那么什么是一致性哈希呢?名字听起来很厉害 ...

  9. JavaScript反爬之哈希算法

    载要 哈希算法是 JavaScript 中和 Python 中的基本实现方法,遇到 JS 加密的时候可以快速还原加密过程,有的网站在加密的过程中可能还经过了其他处理,但是大致的方法是一样的. 消息摘要 ...

最新文章

  1. 中国联通:联通集团正研究混改 具体实施方案在讨论中
  2. InnoDB O_DIRECT选项漫谈(一)【转】
  3. OGR示例:写shp,求面与面的交和差操作
  4. 前端学习(516):两列布局的第三种解决方案
  5. linux下的RPC
  6. AngularJs 冷兵器杂谈
  7. 高中必背88个数学公式_高中数学:必修+选修全部知识点精华!附高考必背203个公式...
  8. 前端开发 表格元素 单元格的合并 0229
  9. python按时间分类数据_Pandas / Python – 按时间段分组数据
  10. 学习日常笔记day11cookie及session
  11. mysql数据库优化总结 有图 有用
  12. 梦之翼网络LAMP技术博客正式成立!
  13. 九款优秀的企业项目协作工具推荐
  14. 10分钟临时邮箱,无限邮箱
  15. 费曼算法(Feynman algorithm)
  16. 在ubuntu中使用7z压缩命令分卷压缩超大文件
  17. PCA(主成分分析)及源码
  18. ASP.NET 简介
  19. php开心农场游戏源码,解密开源版开心农场游戏小程序分享
  20. 计算机的应用范围图表,Excel2013中各类曲面图气泡图雷达图等图表的效果及功能说明...

热门文章

  1. SARIF:DevSecOps工具与平台交互的桥梁
  2. Tomcat服务器搭建
  3. 自主实现HTTP项目——1
  4. 《操作系统》实验四:预防进程死锁的银行家算法
  5. 详解TableStore模糊查询——以订单场景为例
  6. MongoDB删除字段
  7. Standford优质计算机课程资源
  8. javascript sha512算法 加密
  9. build.gradle.kts添加maven仓库
  10. UserDefault和Notification