最近看到一个项目,用明文存储的密码,让人不忍直视,所以就想聊聊密码的存储以及登陆过程中密码传输的那些事儿。
首先就来看看密码存储,密码不能明文存储相信这个都不会有异议,那应该如何存储呢?
方案1: 加盐哈希
相信这个方案也是大多数公司目前使用的方案,至于哈希算法的话,普遍都采用MD5、SHA1、SHA256等算法。加盐的方式也各不相同,比如在密码尾部、在密码中间、在密码头部增加随机盐,有的甚至会使用多次HASH。
不仅如此,甚至可以每次用户设置密码的时候,都为每一个用户生成随机盐,并将随机盐与用户信息一并存储(有时为了混淆,最好将随机盐与密码分表存储,也不要起SALT之类的列名)如此相信即使攻破的数据库,想要破解用户密码也是相当困难的。
后续如果收到用户登陆请求,取出用户随机盐并通过相同的算法进行计算,将结果和数据库中密码相对比就可以判断用户密码是否输入正确。
由于摘要算法的不可逆性,其实一定程度上就限制了登陆过程中用户密码的传输方式。例如:假设服务器的密码转换算法为MD5(SALT + PASSWORD),那么登陆时,有几种选择:
- 传明文密码,在服务器完成密码转换后与数据库中密码进行比对;这种方式在非HTTPS情况下还是相当危险的,如果你是HTTPS的话,也可以用这种方式,但也不是太优雅;
- 将用户随机盐发送给客户端,客户端再使用SHA256(SALT+PASSWORD)计算之后将结果传送给服务器,服务器直接与数据库中的匹配。这种方式虽然不再明文,但是存在两个问题:如果客户端是浏览器,你就很容易暴露你服务器内部的密码转换算法;如果你的随机盐是每个用户1个随机生成的,那么必然会存在多次交互,首先要根据用户登录名去查出其随机盐返回给客户端,之