摘要算法(哈希算法)
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. |
摘要算法(哈希算法)相关推荐
- C# MD5摘要算法、哈希算法
MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致.是计算机广泛使用的杂凑算法之一(又译摘要算法.哈希算法) MD5算法具有以下特点: 1.压缩 ...
- python hashlib 哈希算法
写在篇前 哈希加密算法应用非常广泛,包括数字签名,身份验证,操作检测,指纹,校验和(消息完整性检查),哈希表,密码存储等.在密码学中,好的哈希算法应该满足以下两个条件:一是无法从哈希值解密原始消息 ...
- 数据结构与算法之美-哈希算法
哈希算法的定义和原理 将任意长度的二进制串映射为固定长度的二进制串. 这个映射的规则就是哈希算法,而通过原始数据映射之后得到的二进制串就是哈希值. 设计一个优秀的哈希算法需要满足: 从哈希值不能反向推 ...
- 群人各说什么是哈希算法?
这个HASH算法不是大学里数据结构课里那个HASH表的算法.这里的HASH算法是密码学的基础,比较常用的有MD5和SHA,最重要的两条性质,就是不可逆和无冲突. 所谓不可逆,就是当你知道x的HASH值 ...
- 21 | 哈希算法(上):如何防止数据库中的用户信息被脱库?
问题:对于用户信息中的密码,你会如何存储用户密码?仅仅 MD5 加密一下存储就够了吗?--哈希算法 什么是哈希算法 哈希算法的定义和原理:将任意长度的二进制值串映射为固定长度的二进制值串,这个映射的规 ...
- 【数据结构与算法】哈希算法
一.什么是哈希算法? 1.定义 将任意长度的二进制值串映射成固定长度的二进制值串,这个映射的规则就是哈希算法,而通过原始数据映射之后得到的二进制值串就是哈希值. 2.如何设计一个优秀的哈希算法? ①单 ...
- 面试官:怎么改进哈希算法实现负载均衡的扩展性和容错性?我:...
面试官:怎么改进哈希算法实现负载均衡的扩展性和容错性? 什么是哈希算法 数据结构中我们学习过哈希表也称为散列表,我们来回顾下散列表的定义. 散列表,是根据键直接访问在指定储存位置数据的数据结构.通过计 ...
- 图解一致性哈希算法,看这文就够了!
作者 | LemonCoder 来源 | 后端技术学堂(ID:lemon10240) 很多同学应该都知道什么是哈希函数,在后端面试和开发中会遇到「一致性哈希」,那么什么是一致性哈希呢?名字听起来很厉害 ...
- JavaScript反爬之哈希算法
载要 哈希算法是 JavaScript 中和 Python 中的基本实现方法,遇到 JS 加密的时候可以快速还原加密过程,有的网站在加密的过程中可能还经过了其他处理,但是大致的方法是一样的. 消息摘要 ...
最新文章
- 中国联通:联通集团正研究混改 具体实施方案在讨论中
- InnoDB O_DIRECT选项漫谈(一)【转】
- OGR示例:写shp,求面与面的交和差操作
- 前端学习(516):两列布局的第三种解决方案
- linux下的RPC
- AngularJs 冷兵器杂谈
- 高中必背88个数学公式_高中数学:必修+选修全部知识点精华!附高考必背203个公式...
- 前端开发 表格元素 单元格的合并 0229
- python按时间分类数据_Pandas / Python – 按时间段分组数据
- 学习日常笔记day11cookie及session
- mysql数据库优化总结 有图 有用
- 梦之翼网络LAMP技术博客正式成立!
- 九款优秀的企业项目协作工具推荐
- 10分钟临时邮箱,无限邮箱
- 费曼算法(Feynman algorithm)
- 在ubuntu中使用7z压缩命令分卷压缩超大文件
- PCA(主成分分析)及源码
- ASP.NET 简介
- php开心农场游戏源码,解密开源版开心农场游戏小程序分享
- 计算机的应用范围图表,Excel2013中各类曲面图气泡图雷达图等图表的效果及功能说明...