你有没有想过一个问题——当你在一个网站上输入密码点击登录的时候,网站拿什么来确认"你就是你"?
最直接的答案是存一份你的密码。但稍微有点安全常识的人都知道,明文存密码是灾难性的。一旦数据库泄露,几千万用户的密码就全裸奔了。
可网站又确实能认出你的密码对不对。这背后靠的就是哈希函数(Hash Function)——计算机科学里最不起眼却又最不可或缺的发明之一。
什么是哈希函数
哈希函数本质上是一个不可逆的压缩器。你往里面丢一段任意长度的数据,它吐出一个固定长度的"摘要",通常是一串看起来毫无规律的十六进制数字。
比如你输入"Hello",SHA-256(一种常见的哈希算法)会输出一段64位的十六进制码。你输入"Hellp"——就改了一个字母——输出变成完全不同的另一串。
两次输出之间没有任何相似之处。哪怕输入只差一个比特,输出也是天壤之别。这就是哈希函数的"雪崩效应"。
为什么不可逆
哈希函数的核心设计就是"单向"的。你可以从输入算到输出,但不能从输出反推回输入。
举个直觉化的例子:我告诉你"我脑子里想了一个数,它除以7余3",你能猜到这个数是多少吗?可能是10,可能是17,可能是24,可能是7945。有无限种可能。这就是单向。
但哈希函数比这个例子更复杂。它通过非线性运算、位混淆、多轮迭代来确保三点:第一,输出看起来完全随机;第二,输入的任何微小变化都会导致输出剧烈变化;第三,不可能从输出倒推出输入。
哈希在生活中做什么
存密码。 网站存的是密码的哈希值,不是密码本身。你登录时输入密码,网站算一下哈希值,跟库里的比较。如果匹配就通过。如果数据库泄露——攻击者拿到的是哈希值,不是密码,他没办法还原。这就是为什么正规网站都叫你"重置密码"而不是"找回密码"——因为他们压根没存你的密码。
校验文件完整性。 你从网上下载一个大文件,网站通常会附带一个哈希值。下载完后你算一下文件的哈希,跟网站的比对——一致就说明文件没被篡改过。
快速查找。 这是哈希最常用的场景。手机通讯录里存了一千个人,你想找"张三"——哈希函数可以计算"张三"的位置直接跳过去,不需要一个一个排查。这种数据结构叫哈希表,是计算机里最基础的神器之一。
去重。 云盘上传文件时先算哈希值。如果库里有相同哈希就说明已经有人传过了,直接把那个文件链接给你,不需要真的再存一遍。
哈希不是加密
很多人会把哈希和加密搞混。区别很关键:加密是为了保密,可逆的,用密钥就能解开。哈希是为了验证,不可逆的,算出来就回不去了。
加密是带锁的箱子,你有钥匙就能打开。哈希是榨汁机,你把水果放进去,出来的果汁就再也不能变回水果了。
哈希也有敌人
不是所有哈希函数都生而平等。MD5曾经很流行但已经被攻破——攻击者可以人为构造两个不同的文件让它们算出同一个哈希值,这叫碰撞攻击。SHA-1也步了后尘。现在业界推荐的是SHA-256和SHA-3这类的强哈希。
还有一类叫彩虹表的技术——攻击者预先算好上亿个常见密码的哈希值,建成一张巨大的反向查询表。拿到哈希值一查就知道原文是什么。对抗彩虹表的方法是加"盐"(Salt):在每个密码后面随机拼一段附加字符串再算哈希。这样就算两个用户用一样的密码,算出来的哈希值也完全不同,彩虹表瞬间失效。
站在密码背后
下次你输入密码点下登录按钮的时候,在你的眼睛看不见的地方,哈希函数正在以微秒级的速度做着一件事——把你的秘密变成一串谁都没办法倒回去的乱码,然后跟另一个乱码比一比是不是同一个。
这个小小的"不可逆"机制,守护着互联网上几乎所有的登录系统、文件校验和数据完整性。它不是加密术那样轰轰烈烈的英雄故事,但它每天都在工作,在你每一次登录的瞬间——默默地把你的秘密保护好。