当我们忘记网站密码的时候,通过点击忘记密码按钮之后为什么网站不是直接告诉我们原来的密码而是需要我们重置密码呢?如下是某网站要求密码重置的流程图:
其实,网站让我们重置密码的原因是因为网站也不知道我们的原密码是多少,所以要求我们通过验证来重新输入一个新密码。为什么网站也不知道我们的原密码呢?这是网站为了保证用户的数据安全做的保护措施。今天我们从信息安全和密码加密存储的两个过程来聊一聊网站是如何存储用户的密码。
1、信息安全
互联网发展的过程中,有一些我们熟知的大公司就曾发生过数据泄露导致用户信息被窃取的问题,如推特用户数据泄露、CSDN用户数据泄露等等,数据泄露最大风险就是用户接到大量的诈骗电话,诈骗人通过网站上窃取到用户的个人精准信息,进而很容易就忽悠到受害人。下图是CSDN用户账户密码被泄露的图:
所以为了保护用户的数据安全,很多的网站都不会直接明文的存储用户的密码,这样一方面即使发生了数据泄露了,也不会对用户产生影响,另一方面是可以有效的阻止公司内部有数据权限的人恶意利用用户的账号做一些损害用户利益的事情。
2、密码的加密存储
服务端保存密码到数据库的时候是不推荐直接保存明文的密码的,通常我们通过hash算法加密,hash算法是不可逆的,无法通过hash算法之后的值得到原来的值。常见的hash算法有MD5、SHA256、RSA等等。
(1)MD5
MD5加密方式会出现不同密码加密之后产生相同的hash(也就是hash冲突),另外MD5加密后一个得到的密文永远是唯一的,如下使用MD5加密得到123456的密文:
原文 | 密文 |
123456 | E10ADC3949BA59ABBE56E057F20F883E |
那么这个密文始终代表明文的是123456,假设我们的MD5密文库足够大,那么我们的密码理论上是很容易被破解的。如下是一个在线的MD5转换为原文的工具:
这种直接MD5的方式不安全,我们可以考虑密码的复杂度来提高密码安全等级,所以我们在设置的密码的时候网站会要求我们密码要含有大小写字母、符号等要求,如下是常见的密码要求:
通过复杂设置的之后,想要破解密码就是一件比较困难的事情了。
(2)SHA256
SHA256加密方式极大地降低了不同密码加密之后hash冲突问题,它比MD5抗碰撞能力更强。SHA256和MD5一样,同一个密码是固定的密文的问题,会存在彩虹表攻击。
彩虹表攻击是攻击者利用预先计算并存储大量hash值和对应的原始密码,攻击者在知道用户密文hash值的情况下,利用彩虹表来快速的查找原始密码的一种攻击方式,如下所示的彩虹表:
原密码 | 密文的hash值 |
123456 | e7qwerty84kjdsjhdhjdfsj |
longxia | w2sderft653wdrkfutj456 |
攻击者获取到密文的hash值后比对彩虹表得到原密码,进而达到破解用户密码的目的。
(3)hash + 随机盐
常见的密码加密方式是通过hash+随机盐值的方式来保存密码,这样可以保证两个用户使用相同的密码,由于其盐值不同而得到的hash值也不会相同,其次攻击者需要为每一个盐值生成单独的彩虹表,这样极大的增加了攻击的复杂性。
当用户密码传递服务端后,首先要生成一个随机的盐值,然后将这个盐和密码经过哈希计算得到hash值(密文);将这个密文和盐和存储到数据表中。
用户登录的时候,首先根据name查询用户在数据库中的数据,然后服务端根据盐+用户输入的密码进行hash计算得到hash值A,拿A与数据库中的密码hash值B做对比,如果A和B相同则可以让用户登录,否则提示账号或者密码不对。
总结:
(1)从信息安全的角度上来说,不推荐直接使用明文存储用户的密码,推荐使用hash+随机盐的方式来保存密码。
(2)用户的密码是hash密文的形式保存在数据库中,由于hash算法是不可逆的,这样拿到hash密文之后服务端也无法解析出用户的原始密码,所以当用户忘记密码的话只能让用户走重置密码的流程。
(3)现在网站为了更好地保护用户数据安全,常常采用扫描登录、手机验证码等无密码的方式登录。