web账户的口令不能直接明文存储,这样太不安全了,需要加密存储。
- 存储策略—— 基于安全哈希算法加密存储用户的口令
估计基于安全哈希算法的存储方式应该已经广泛使用了,不过奇怪的是网上难以找到相关应用的详细资料。哈希算法可用于保障信息的完整性、抗抵赖性, 属于单向算法,即便哈希的结果被截获,对方也是无法还原出明文的。如果在哈希的过程中加入盐值,那就更好了,可以起到混淆的作用。盐值这个概念找不到定义,大概是指用户间相互不同的信息,常见的用户名、用户邮箱、账号注册时间等。
类似地,选择基于哈希的消息认证码(HMAC)也可用于身份认证,安全性更强,如果各位对单纯的hash不放心,可以使用HMAC。
也有资料提到通过非对称加密算法加密后存储,比如RSA,个人觉得这种方法的安全性不如哈希算法,使用起来也麻烦,需考虑系统后台的密钥管理,而一旦密钥泄露,所以信息也就都白加密了。
2. 算法的选择
哈希算法有很多,常见的有MD5和SHA系列。现在有个叫彩虹表的东西,穷举某个哈希值所对应的明文,导致了MD5和SHA-1已经不再安全。而SHA-256或SHA-512目前还是比较安全的,而且计算消耗的资源不会比MD5或SHA-1差太多。从代码实现的角度考虑,各算法的参数都一样,返回值类型也一样,只是函数名和返回值长度变了,所以如果已使用了MD5或SHA-1,可很方便地切换到更安全的算法上。
3. 添加盐值
以盐值为用户名,算法为SHA-256为例,用户最终存储在后台的口令就可以为SHA256(" 用户名+口令 " )。而登陆的时候,有两种验证策略:
- 可在客户端计算出SHA256("输入的用户名+输入的口令"),将计算的结果明文传输给服务端,由服务端比较该值与后台数据库中存储的是否相同。
- 将输入的用户名,口令加密传输到服务端,在服务端计算 SHA256("输入的用户名+输入的口令"),再与数据库存储的内容做比较。加密传输现在比较流行的方法是HTTPS,这里就不多说了。
可以看到,服务端是不知道用户的口令明文是什么,所以即便数据库攻破,也不会泄露用户的口令。
再说说添加盐值的好处。大家都知道,最常见的口令是123456,假设有100个用户都这么设置了,那么如果不加盐值,这100个用户后台加密存储的口令就一摸一样了,这就是一个安全隐患。加了盐值还可以增加彩虹表碰撞的难度,就算用户使用了最简单的口令,加了盐值后也还是难以破解的。
盐值最好选择用户注册后,就不会再改变的信息,或是由这些信息计算后的另一个值。比如,如果盐值设置成了用户邮箱,那就要确保这个邮箱不能修改,否则一旦邮箱改了,HASH("新邮箱+口令")≠ HASH("旧邮箱+口令") ,从而用户改了邮箱就不能再登录了。