如何使数据库中的密码更安全:哈希、加密和加盐
0X00 前言
设计一个系统,不论是 Web 还是其他的什么形式,通过用户名和密码认证也是一个再正常不过的事情了。但是如何保存密码却是一个值得讨论的问题,相信各位最开始的一个有用户名和密码的程序多半也是用明文存储的密码吧 🤓
这里总结了六种比较常用于密码存储的方式,接下来可以逐一进行简单的分析以帮助我们更好的保护用户的密码
一清二白:明文存储密码,直接存 password
掩耳盗铃:使用 BASE64
之类的编码,存储为 cGFzc3dvcmQ=
盘古之法:使用早已不再安全的 md5
之类的摘要算法,存储为
5f4dcc3b5aa765d61d8327deb882cf99
祖宗之法:使用也已经不再安全的 sha-1
之类的摘要算法,存储为
5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8
凑合能用:使用现代的安全的例如 sha-256
之类额算法,存储为
5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
现代手段:采用系统化的多次迭代的加盐哈希方式加密,例如常见的 PBKDF2
有兴趣的话可以把我上面的这几个 md5/sha-1/sha-256 拿来到 CrackStation 尝试解一下,就知道弱密码究竟有多危险了。
不过在开始之前要先进行一些简单的科普,以便于能够比较好的理解后面的东西。
名词解释
拖库:简单来说就是有不怀好意的小老弟获取了你数据库的访问权限,甚至将其 dump
然后下载下来了
撞库:当你有某个库的用户名和密码明文了,其实可以拿着用户名密码去其他系统也尝试登录,因为很多人的用户名和密码在各个系统都是一样的,比如同一个邮箱注册的密码也用的完全相同
碰撞:一般是说 hash 碰撞,在有一对原文和对应的 hash 值后再找到一个 hash 值相同但原文不同的的方法
盐:加盐是一种在进行散列前向原文指定位置插入内容,将散列前的原文变得很长从而使彩虹表等方式失效的行为
密码破解
常见的几种破解密码的方式有:暴力破解、用字典的暴力破解、彩虹表、社会工程学。
其中暴力破解最为暴力(废话噢),就是把所有可能的密码组合一个个的尝试一直尝试到天荒地老。如果是一个 8 位密码且只由大小写数字构成的话也有 62^8=218340105584896 这么多种组合,就算每秒钟能算出来十万个也需要七十年才能完全遍历一遍;
其次是用字典,字典就是将常用的弱密码、生日这种存起来,暴力破解的时候不再尝试所有组合,而是从字典中逐个取出来尝试,速度较快但是成功率降低了,毕竟只尝试了可能性最大的一小部分密码;
彩虹表也是类似于字典,但是字典每条只是一个密码,彩虹表是密码明文与 hash 之后的 key-value 对,当数据库被拖/泄露了之后,可以尝试拿泄露出来的 hash 值来反查密码原文;
社会工程学听起来好像很野,但是谁还没有过用生日和手机号作为密码解密的尝试呢 🤣