seegongsik
安全

怎么工作 哈希 怎么保护密码

把水果放进榨汁机一打,就成了果汁。光看果汁,没法把放进去的是哪些水果、各放了多少,原样还原出来。安全哈希也差不多:放进一个值,出来一段短短的指纹,但没办法从指纹倒推出原来的值。所以网站不会把你的密码原样存起来,只存这段指纹。

01

只能往一个方向走

有一种计算,不管放进什么值,都会给出一段固定长度的短指纹,这就叫安全哈希。同一个值放进去,出来的指纹永远一样;哪怕只改一个字,指纹也会变得面目全非,比如把“apple”改成“apples”,算出的两段指纹就毫无相似之处。
最重要的性质是方向。从输入做出指纹很容易,可从指纹倒算出原来的输入,没有办法。水果能变成果汁,果汁却变不回水果。所以它叫单向函数。

输入pw-2026
→←
指纹?
把输入变成指纹

用“做指纹”按钮把输入变成指纹。接着点“回去”,会发现路是堵死的。

往前的路一下就通了,往回的路却堵着。这道堵,就是安全哈希的要害:光凭指纹,算不出原来的值。
这个性质用得最多的地方是密码。如果把密码原样存着,谁往存储里看一眼就全知道了。所以要换个办法。

02

不存密码,存指纹

把密码一字不差地存下来,叫明文存储。这样一来,存储一旦被攻破,甚至只是有人往里看一眼,所有用户的密码就都暴露了。很多人在好几个地方用同一个密码,损失还会蔓延到别的网站。
所以要把密码放进哈希,只存出来的指纹。存储里排着的,就只剩一条条无法还原的指纹。

密码sun-flower-7
→
存储里留下的东西...
点两种方式比一比

点“明文存储”和“指纹存储”比一比。明文存储里密码原样可见,指纹存储里只留下无法还原的指纹。

明文存储那边,密码一览无余;指纹存储那边,只剩认不出来的指纹。不过,有了指纹也不能完全放心。攻击者虽然没法倒算指纹,却可以把常见的密码一个个放进哈希,看看有没有哪个算出同样的指纹。
所以专门用于密码的哈希会故意算得很慢,让这种逐个试的办法难以得逞。可如果不存密码,登录时又怎么确认密码对不对呢?

03

把输入变成指纹来确认

利用“同一个值永远得出同一个指纹”这个性质来确认。登录时用户输入密码,服务器就把这个输入再放进哈希,做出新指纹,再跟存好的指纹比一比。
两个一样,说明输入的是同一个密码,就放行;不一样,就拦下。不用把原来的密码拿出来看,只比指纹就能确认。

选一个输入
存好的指纹a7-c2-90
?
输入的指纹?
选一个输入再点确认

选一个输入,点“确认”。输入的指纹和存好的指纹一样就通过,不一样就被挡住。

只有输入正确的密码时,指纹才一致,才通过。只差一个数字的密码,也变成了完全不同的指纹,被挡了下来。只存指纹,用指纹比对来确认,这样没有原文也能分辨对错。
哈希的用处不只在密码上。把下载的文件算出的指纹,和公开的指纹比一比,就能知道文件在传输途中有没有被改过。这正是守护上一课讲的完整性的手段。

04

和数据单元里的哈希目的不同

哈希这个词,在数据单元里也出现过。那里是把值变成格子号,好快速找到想要的资料。目的是又快又均匀地安排位置,偶尔两个值落进同一个格子,也不算大问题。
安全哈希样子相似,目的却不同:从指纹回不到原来的值,而且要找出算出同一个指纹的两个不同输入,实际上也做不到。

点两边对比目的

点两边,比一比两种哈希的目的。数据单元里的哈希是为了快找,安全哈希是为了无法还原。

同样叫哈希,数据单元里用它是为了快找,安全领域用它是为了无法还原。目的决定了这件工具需要什么性质。

可见,名字相同的工具,用在不同地方,看重的性质也不一样。格子号和指纹看上去都只是一串短短的数字,背后要求的性质却完全不同。在安全领域,最宝贵的就是无法还原。现在从头到尾理一遍。

05

小结

归纳起来是这样:安全哈希把输入变成单向的指纹,从指纹回不到输入。所以不存密码本身,只存指纹。登录时把输入再变成指纹,跟存好的指纹比,一样就放行。
这和为了快找而用的数据单元里的哈希不同,是为了无法还原而用的哈希。

依次点四个要点
从上往下依次点下面的要点

依次点要点回顾一下。(单向指纹 → 只存指纹 → 用输入的指纹确认 → 和数据单元里的哈希目的不同)

现在你知道了,不把密码原样留着也能守住它。一段无法还原的指纹,让存储和确认都安全了。谁手里都没有原文,能泄露的秘密也就少了。
不过还剩一个弱点:同一个密码永远得出同一个指纹,两个人用同一个密码,指纹就一样;攻击者还能事先把常见密码的指纹列成一张表。下一课讲盐,也就是用来堵住这个弱点的办法。

一句话总结安全哈希只朝一个方向把输入变成指纹:从输入做出指纹很容易,从指纹倒算出输入却做不到。所以密码不原样存,只存指纹。就算存储被攻破,里面也只有指纹,密码不会马上暴露。登录时把输入的值再变成指纹,跟存好的指纹比,一样就放行;这之所以行得通,是因为同一个输入永远得出同一个指纹。数据单元里的哈希是为了快找,安全哈希则是为了无法还原。不过,拿常见密码一个个去试的攻击依然存在,所以专门用于密码的哈希会故意做得很慢。
← 安全
如果有帮助,请支持我们