哈希函数(Hash Function,意译为 “散列函数”)是一种从任何一种数据中创建小的数字 “指纹” 的方法。散列函数把消息或数据计算成摘要 (Digest),使得数据量变小,将数据的格式固定下来。该函数将数据打乱混合,重新创建一个叫做哈希值(Hash value,又叫散列值)的指纹。
为什么叫 “Hash”?
麦当劳售卖薯饼 (Hash Brown) 早餐,即将一整个马铃薯削成丝状,再将丝状马铃薯重新油炸成一整个薯饼。由于本质上是将原先的一个整体打散再重新组合且过程不可逆,正好符合该类算法的设计思路,于是称该类算法为哈希 (Hash) 算法。
哈希算法如何保护密码?
用户注册时,密码先在前端进行哈希,哈希值传回后端数据库存储。用户登录时,输入的密码在前端进行哈希,然后传回后端进行比较。
有时,为了增强哈希算法的抗碰撞性,我们会给明文加上 “盐值”🧂。盐值会设置成一个随机的字符串,然后和明文进行拼接。由于加盐后的明文非常长,因此几乎不可能被碰撞。下面的 CTF 示例就有加盐的 MD5。
MD5 信息摘要算法 (MD5 Message-Digest Algorithm) 是 MD 系列算法的最常见版本。算法会生成一个 128 位的哈希值(长度为 32 的十六进制值)
1 | // : All variables are unsigned 32 bit and wrap modulo 2^32 when calculating |
MD5 算法于 1993 年发现 “伪碰撞”,1996 年发现部分碰撞。2004 年,中国的王小云教授宣布发现了 MD5 的完整碰撞,该算法被证明不具有抗碰撞性。
如果自己写破解脚本,需要通过逆向知道原文的构成规律 —— 个人计算机大概率是无法承受完全穷举的工作量的,所以我们需要有目的、有限制地爆破 Hash。下面举几个例子:
这个比赛在 2025/7/12 进行。当时我们发现直接运行程序,不会输出 query: ...,这个 (0x686d4080 < *(longlong *)(unaff_RBP + 200)) && (*(longlong *)(unaff_RBP + 200) < 1752052052) 条件在控制。
向上查看发现 unaff_RBP + 200 实际上是从 FUN_140001493 中的 _time64 得到的 UNIX 时间戳。转换发现条件是本机 UTC 时间为 2025/7/9 00:00:00 - 2025/7/9 09:07:32 时,执行函数体并输出该时刻的查询字符串。此时断网并调整本机时间。
哈希函数(Hash Function,意译为 “散列函数”)是一种从任何一种数据中创建小的数字 “指纹” 的方法。散列函数把消息或数据计算成摘要 (Digest),使得数据量变小,将数据的格式固定下来。该函数将数据打乱混合,重新创建一个叫做哈希值(Hash value,又叫散列值)的指纹。
为什么叫 “Hash”?
麦当劳售卖薯饼 (Hash Brown) 早餐,即将一整个马铃薯削成丝状,再将丝状马铃薯重新油炸成一整个薯饼。由于本质上是将原先的一个整体打散再重新组合且过程不可逆,正好符合该类算法的设计思路,于是称该类算法为哈希 (Hash) 算法。
哈希算法如何保护密码?
用户注册时,密码先在前端进行哈希,哈希值传回后端数据库存储。用户登录时,输入的密码在前端进行哈希,然后传回后端进行比较。
有时,为了增强哈希算法的抗碰撞性,我们会给明文加上 “盐值”🧂。盐值会设置成一个随机的字符串,然后和明文进行拼接。由于加盐后的明文非常长,因此几乎不可能被碰撞。下面的 CTF 示例就有加盐的 MD5。
MD5 信息摘要算法 (MD5 Message-Digest Algorithm) 是 MD 系列算法的最常见版本。算法会生成一个 128 位的哈希值(长度为 32 的十六进制值)
1 | // : All variables are unsigned 32 bit and wrap modulo 2^32 when calculating |
MD5 算法于 1993 年发现 “伪碰撞”,1996 年发现部分碰撞。2004 年,中国的王小云教授宣布发现了 MD5 的完整碰撞,该算法被证明不具有抗碰撞性。
如果自己写破解脚本,需要通过逆向知道原文的构成规律 —— 个人计算机大概率是无法承受完全穷举的工作量的,所以我们需要有目的、有限制地爆破 Hash。下面举几个例子:
这个比赛在 2025/7/12 进行。当时我们发现直接运行程序,不会输出 query: ...,这个 (0x686d4080 < *(longlong *)(unaff_RBP + 200)) && (*(longlong *)(unaff_RBP + 200) < 1752052052) 条件在控制。
向上查看发现 unaff_RBP + 200 实际上是从 FUN_140001493 中的 _time64 得到的 UNIX 时间戳。转换发现条件是本机 UTC 时间为 2025/7/9 00:00:00 - 2025/7/9 09:07:32 时,执行函数体并输出该时刻的查询字符串。此时断网并调整本机时间。