Day19-不能说的秘密(一)

前言

讲完 session 之後,接下来这几天要来讲讲跟密码有关的安全性议题,毕竟如果使用者的密码不小心被骇客偷了去,那不管网站的流量管制做得多好、session 安全性有多高,最後也都会是功亏一篑

为什麽不给我原密码

从使用者的角度来看,我想大家应该都有过忘记密码的经验,那为什麽当你按下「忘记密码」时,网站总是要求你重设密码(除了某和X租车 ?),而不直接把密码寄到你的信箱呢?答案就是因为网站根本不知道你的密码是什麽!

大部分人第一次听到这个答案时都会非常错愕,心想「如果网站不知道我的密码是什麽,那他要怎麽知道我输入的密码对不对」,这就是密码学的神奇之处了,网站确实可以在不储存密码明码的情况下,验证你输入的是不是正确的密码,这个待会我们再来细讲

而从网站开发者的角度看,虽然直接在网站资料库储存所有使用者的密码非常方便,反正使用者输入密码之後就到资料库里面比对一下就好了,但其实这样做有非常大的风险,万一哪天网站的资料库被骇客入侵,或是被内部员工有意无意泄漏出去,那就会有非常多使用者被盗用,造成无法估计的损失

所以说关於储存密码这件事,虽然大多网站开发者都觉得自己家的资料库很安全,绝对不可能被骇客入侵,但还是应该要做好准备,尽量做到「即使资料库被骇了,使用者的密码也不会泄漏出去」这样的程度才对

把密码加密起来怎麽样?

如果直接把使用者的密码明码存起来太不安全,那先加密起来再存可以吗?这样即便资料库被攻破,只要骇客拿不到密码,应该就不可能得到原本的密码吧

以现今最流行的对称式加密法 AES256 为例,如果把资料库里面所有的密码用 pa55w0rd 作为 key 加密起来,大概会长成这个样子

aes

如此一来即便整个资料库都泄漏出去了,只要骇客不知道加密用的 key 是什麽,就无法还原出原本的密码,因此会比原本直接存明码来得安全

虽然说是这麽说,但其实也没安全到哪里去,因爲使用者要登入时,後端必须确认使用者输入的密码正确,所以还是必须把 key 放在 server 上用来解密。既然是放在 server 上,那骇客就还是有机会拿到,你想想他都能偷到你家资料库了,拿到加密用的 key 其实也不是太难的事情

而且这样做还有另一个隐忧:因为公司内的员工可能会知道 key,所以就可以从资料库得到使用者的密码。如果你知道 Facebook 的工程师只要想要就能得到所有人的密码,应该也不太放心吧,尤其很多人都在多个网站使用同样的密码

所以结论就是因为无法保证 key 的安全,所以不建议用加密的方式保存密码

把密码经过 SHA1 杂凑再存起来

我听说杂凑(hash)是不可逆的,那用杂凑总可以了吧?

不太熟悉编码、杂凑、加密三者区别的话,可以先看完 「一次搞懂密码学中的三兄弟 — Encode、Encrypt 跟 Hash」 再往下看,比较不会搞混哦

没错!杂凑是不可逆的,下图三个密码就是经过 SHA1 杂凑过的结果,像 Luka 的密码 hash 过後是 1785bf0ed0f6346210af2d64b310a99b4024ce44,而这串东西无法经由运算反推回原密码

hash

对於杂凑函数而言,相同的输入一定会得到相同的输出,因此当使用者 Luka 要登入时,API Server 就把他输入的密码拿去经过 SHA1 杂凑,如果算出来的杂凑值跟资料库内那一大串一样,那就代表 Luka 有极高机率输入了正确的密码,所以就放行让他登入

但可别忘记了,虽然杂凑值无法直接反推回原密码,但你可以用电脑把长度为 8 的字串都用 SHA1 杂凑过一遍,譬如说从 00000000 一路算到 zzzzzzzz,然後建一个表

如下图,因为 SHA1 的碰撞机率极低,如果计算的过程中找到某字串 hash 後刚好是 1785bf0ed0f6346210af2d64b310a99b4024ce44,那该字串 love1234 就非常有可能是 Luka 的密码

hash

虽然这听起来很不可思议,真的要做也是一个大工程,但因为现在电脑的运算速度非常快,所以已经有人做过了。只要到 MD5Hashing.net 输入你想要破解的杂凑值,甚至不需要告诉他是哪一种演算法,他就会帮你查表找出来。像我输入 Luka 那一串 1785bf0ed0f6346210af2d64b310a99b4024ce44,就能知道他是 love1234 经过 SHA1 杂凑的结果,超厉害的

hash2

而且这个网站支援的杂凑演算法有超过六十种,包括大家最常用的 MD5SHA1SHA256Tiger128 等等,所以你换其他杂凑法也没有用,只要骇客拿到密码杂凑值,要得到原本的密码也不会太难

小结

今天虽然没有总结出到底该怎麽储存密码,但我们明天会继续往下探讨其他解决方法,如果对於今天的内容有什麽问题欢迎在下方留言,没有的话我们就明天见啦


<<:  Web应用扫描工具-Arachni小蜘蛛(中)

>>:  【心得】不同 gradient 使用方式-- conic-gradient()

[第十九只羊] 迷雾森林舞会XIII 设定form 绑定dom 同步房间(单押)

天亮了 前晚是1号玩家死亡 关於迷雾森林故事 反指标 洛神:2号玩家请继续发言 2号:1号是猎人他带...

多容器编排与管理 Docker Compose简介

上篇回顾 设定档格式 YAML Docker太多文章介绍了, 小弟我K8S也没那麽熟稔 就介绍自己熟...

【Day 28】设置开发环境 & 开发

tags: 铁人赛 蚵仔面线 萝卜丝饼 开发环境 env virtualenv 美食与废言 前阵子常...

ARM 架构的韧体设计?

目前正在决定是否要学ARM 架构的韧体设计? 因为看到文章 https://www.pttbrain...

Day 11 - Algebraic Data Types

yo, what's up? Product Type Product types 允许同时存在两种...