密码存储方案

为何不能明文存储密码

明文存储, 会面临多方面的安全威胁, 很难保证密码不被泄露. 密文存储的话, 即时被拖库, 黑客也难以获取用户的明文密码.

为何不能用AES之类的加密算法

这涉及到怎么保存用来加密解密的密钥,虽然密钥一般跟用户信息分开存储,且业界也有一些成熟的、基于软件或硬件的密钥存储方案。但跟用户信息的保存一样,想要密钥百分百不泄露,不可能做到。用这种方式加密密码,能够降低黑客获取明文密码的概率。但密钥一旦泄露,用户的明文密码也就泄露了,不是一个好方法。 
另外,用户账户系统不应该保存用户的明文密码,在用户忘记密码的时候,提供重置密码的功能而不是找回密码。

为何不用MD5或SHA1存密码

MD5和SHA1已经被严格证明存在漏洞, 很容易就能人为制造哈希碰撞, 现实中也出现对应的破解事故, 比如微软的数字签名被伪造.

为何不用SHA256或SHA512存密码

可被字典表或彩虹表破解, 速度非常快.

为何不用SHA256/SHA512加盐的方式存密码

虽然加盐可以避免攻击者使用预先计算好的彩虹表或字典表破解, 使之必须单独针对每个密码进行破解计算, 但如今的GPU/FPGA的并行计算效率非常夸张. 例如开源的hashcat项目, 使用当前NVIDIA的2080TI游戏显卡, 计算MD5的速度就可达500亿次/s, SHA256为74亿次/s, SHA512为23亿次/s
如8位密码, 数字和小写字母的组合, 一共2821109907456(2亿亿)种可能, 使用SHA256加盐加密, 而攻击者使用2080TI计算所有情况, 只需耗时6分钟, 破解出来的期望时间为3分钟. 
而盐和加密算法通常也很难保证不被攻击者取得, 所以单独破解每个密码在如今GPU算力高涨的时代是完全可行的.

bcrypt的优势和局限

bcrypt是专门为密码存储而设计的算法,基于Blowfish加密算法变形而来,由Niels Provos和David Mazières发表于1999年的USENIX。 
bcrypt最大的好处是有一个参数(work factor),可用于调整计算强度,而且work factor是包括在输出的摘要中的。随着攻击者计算能力的提高,使用者可以逐步增大work factor,而且不会影响已有用户的登陆。 
缺点是不支持内存占用调整且容易被FPGA加速, 验证速度非常慢, 即时将参数调整到最低, 在双核4G的服务器上也只有1000的QPS.

Argon2算法

Argon2是在2015年赢得密码哈希竞赛(PHC)的密码哈希函数, 分为Argon2i, Argon2d和Argon2id三个变种。 
Argon2id是Argon2i和Argon2d的混合体,使用依赖于数据和独立于数据的内存访问的组合,这使Argon2i能够抵抗侧通道缓存计时攻击,并使Argon2d能够抵抗GPU破解攻击。 
可利用大量内存和大量计算资源进行 Hash 计算。 
参数可调整, 在性能和安全性上有着比较好的折中方案.

其他现有算法的缺点

PBKDF2计算过程需要内存少所以可被GPU/ASIC加速. 
scrypt不支持单独调整内存或计算时间占用且可能被ASIC加速并有被旁路攻击的可能.

将采用的方案

  • 首先使用CSPRNG(Cryptographically Secure Pseudo-Random Number Generator)生成512位的盐.
  • 将密码和盐直接拼接, 使用sha512,将用户密码归一化为64字节hash值.
  • 使用Argon2id算法, 512KB内存占用, 迭代一次的配置进行密码哈希计算得出最终结果.
  • 将输出的字节流转为标准base64字符串存储.
  • 在Macbook pro上测试, 速度可达2500op/s.

你可能感兴趣的:(编程)