Hash英文含义:切细,剁碎,重新拼凑,重新表述,杂凑。
哈希算法:指的是一类算法,即使用哈希算法对数据进行处理,处理之后得到一个Hash值来重新表述原数据。
一、哈希(Hash)算法说明
举例说明:
- 比如密码的保存:直接保存明文密码不安全,可以通过哈希计算之后保存哈希计算后的Hash值。如下所示,使用的是MD5哈希算法计算后的Hash值。
密码 | MD5哈希算法 | Hash值 |
123456 | >>>>密码哈希计算>>>> | e10adc3949ba59abbe56e057f20f883e |
32165234 | >>>>密码哈希计算>>>> | d553d148479a268914cecb77b2b88e6a |
98765453 | >>>>密码哈希计算>>>> | 6c44e5cd17f0019c64b042e4a745412a |
哈希(Hash)算法特点:
- 哈希算法计算输入的值长度可以不一致,输出的Hash值长度一致(如上表所示MD5的Hash值都是32为字母+数字的组合。注意:Hash值长度一致只是出于安全考虑,不同的Hash算法为了便于管理,生成的Hash值都是固定长度,Hash算法生成的Hash值长度也可以不一致。)。
- 哈希算法计算的后的值是有限的(如上表MD5的Hash值虽然可以有很多种,但是依然有限,最多36^32种组合。每个位置的字符只能是a-z中的一个小写字母或者0-9中的一个数字,所以一个位置最多有26+10种组合,总共有32个位置,那就是36*36*36*........*36*36=36^32种组合的Hash值)。
- 哈希算法可以自行定义,可以自定义哈希算法(如上表使用的是MD5哈希算法,可以使用SHA256哈希算法、SHA512哈希算法、或者自行设计一种哈希算法)。
- 哈希算法计算后的值不能被解密,只能进行比对,即获得一个MD5哈希计算后的Hash值为6c44e5cd17f0019c64b042e4a7451111,无法直接进行解密,无法使用这个Hash值进行解密出对应的密码值。(注意:可以通过暴力枚举破解的方式或者彩虹表的方式进行破解)
二、自定义哈希(Hash)算法
示例一:
输入:狗、鸭、猫、牛、鼠
哈希算法:定义动物的“叫”为哈希算法
输出哈希值:
输入 | 哈希算法 | Hash值 |
狗 | 叫声 | 汪汪汪 |
鸭 | 叫声 | 嘎嘎嘎 |
猫 | 叫声 | 喵喵喵 |
牛 | 叫声 | 哞哞哞 |
鼠 | 叫声 | 吱吱吱 |
如上表所示,将动物的“叫”定义为一种哈希算法,现在有一个动物“旺财”,我不知道他是什么动物,那可以调用“叫”哈希算法,当输出为“汪汪汪”,那就可以判断这个动物就是“狗”。
示例二:
现在有IP为192.168.8.100-192.168.8.200服务器,要去随机访问两台服务器A、B,且每个IP固定访问其中的一台服务器。就可以设计一种哈希算法。IP尾号对2取余,余数为0的时候访问A,余数为1的时候访问B。
输入:IP地址
哈希算法:IP尾数除2取余
哈希值:0或者1
IP位数 | 哈希算法 | Hash值 | 访问的服务器 |
100 | 对2取余 | 0 | A |
101 | 对2取余 | 1 | B |
102 | 对2取余 | 0 | A |
103 | 对2取余 | 1 | B |
.... | 对2取余 | ...... |
如上表可知,192.168.8.100固定访问A服务器,192.168.8.101固定访问B服务器
三、哈希(Hash)值有限问题解决
如示例一所示,哈希值是有限的,只有汪汪汪、嘎嘎嘎、喵喵喵、哞哞哞、吱吱吱。会存在很多动物哈希计算后存在相同的哈希值。现在有两条狗:一条为“德牧”,一条为“柯基”。现在我想通过hash表来确定这条狗是什么品种,使用上面的方法就有局限性。这就是所谓的Hash值有限问题。
常见的解决Hash值有限的方法:动态扩容法、开发寻址法.........
链地址法(开放寻址法的一种)的理解:
java中的LinkedHashMap使用的方法。如下所示使用哈希加链表的形式能唯一确定一条狗的种类。如果一条狗的Hash值为“汪汪汪”,链表地址为“1”,那这条狗就是德牧狗
四、哈希(Hash)值解密
如果一个密码通过Hash算法计算后得到一个Hash值,Hash值实际上是不能进行解密操作的,但是可以通过暴力枚举的方式来进行Hash值的比对,从而实现解密的间接操作。
密码 | MD5哈希算法 | Hash值 |
123456 | >>>>哈希计算>>>> | e10adc3949ba59abbe56e057f20f883e |
12345sdfsdaf456asdf | >>>>哈希计算>>>> | fb058ee8c0c084255fdaf54ade852292 |
653425 | >>>>哈希计算>>>> | f10ebe823bcd4d60509f8ff121e364a0 |
如上表所示的表格中三个密码通过MD5计算之后得到了各自的Hash值,如果现在直接对Hash值进行解密,是无法解密的。
注意:为什么有的Hash值能在线网页上解密,如123456对应的Hash值为e10adc3949ba59abbe56e057f20f883e,在线网页对e10adc3949ba59abbe56e057f20f883e进行解密为什么能解出来密码123456。(网址https://www.sojson.com/encrypt_md5.html)
其实这种是通过暴力枚举的方式进行解密的,假设密码只有6位数字组成,每个位置只有0-9的数字,那最多破解10^6就是100万次就能破解这个密码。
做法就是将每个密码都使用MD5进行计算,计算后后得到一个Hash值,通过得到的Hash值去和e10adc3949ba59abbe56e057f20f883e匹配,如果123456的进行MD5哈希计算之后得到的Hash值是e10adc3949ba59abbe56e057f20f883e且刚好匹配上,那就可以确定e10adc3949ba59abbe56e057f20f883e解密后的密码为123456。如下图所示:
待解密的Hash值 | 枚举值 | 枚举值MD5计算后的Hash值 | 匹配度 |
e10adc3949ba59abbe56e057f20f883e | 23654 | cb16e9966ff8b9db87d4ab07b1d9c117 | 不匹配 |
98456 | 8c2e6ab9d5c654df3eb46c572e6a3e2f | 不匹配 | |
...... | ...... | 不匹配 | |
123456 | e10adc3949ba59abbe56e057f20f883e | 匹配 | |
...... | ...... | 不匹配 |
对于简单的密码可以通过暴力枚举的方式进行解密,如果是复杂的密码则通过暴力的枚举的方式就不能进行解密,或者说解密的计算量会很大。如对密码“12345sdfsdaf456asdf”对应的Hash值“fb058ee8c0c084255fdaf54ade852292”进行解密,需要枚举36^19以上(直观一点就是(3.6*10)^19以上),即1000亿亿次以上,属于是超算级别的计算量。如下图所示,所以在进行密码设置的时候不要设置过于简单的密码。