美文网首页IT相关计算机编程网络与信息安全
[译]Dropbox是如何安全地存储用户密码的

[译]Dropbox是如何安全地存储用户密码的

作者: __七把刀__ | 来源:发表于2016-11-05 21:22 被阅读795次

最初看到这篇文章是在 @登州知府 的微博上看到的,他的微博上分享了很多好的技术博客,推荐。由于本人英语学的比较烂,翻译的错漏之处请大家指正。原文在这里:How Dropbox securely stores your passwords

众所周知,存储明文密码是一件很糟糕的事情。一旦数据库存储了明文密码,那么用户账号就危险了。因为这个原因,早在1976年,工业界就提出了一套使用单向哈希机制来安全地存储密码的标准(从Unix Crypt开始)。很不幸的是,尽管这种方式可以阻止你直接读取到密码,但是所有的哈希机制都不能阻止攻击者在离线环境下暴力破解它,攻击者只需要遍历一个可能包含正确密码的列表,对每个可能的密码进行哈希然后跟获取到的密码(使用哈希机制存储的密码)比对即可。在这种环境下,安全哈希函数如SHA在用于密码哈希的时候有一个致命的缺陷,那就是它们运算起来太快了。一个现代的商用CPU一秒钟可以生成数百万个SHA256哈希值。一些特殊的GPU集群的计算速度甚至可以达到每秒数十亿次。

过去的这些年,为了应对攻击,我们对密码哈希方法进行了数次升级。在本文中,我们将会为各位分享我们关于密码存储机制的更多的细节以及我们为什么要这么做的原因。我们的密码存储方案依赖三个不同层级的密码保护,如下图所示。为了方便说明,在下图中以及接下来我们省略了字节编码(base64)。

Dropbox存储密码的层级图

我们采用bcrypt作为我们的核心哈希算法,每个用户都有一个独立的salt以及一个加密的key(这个key也可以是一个全局的,通常也叫pepper),salt和key是分开存储的。我们的方法与基础的bcrypt算法在一些重要的方面是不同的。

首先,用户的明文密码通过SHA512算法转换成了一个哈希值。这一步主要是针对bcrypt的两个突出的问题。有些bcrypt的实现中会将用户输入截取为72个字节大小以降低密码熵,而另外有一些实现并没有截取用户输入导致其容易受到DoS攻击,因为它们允许任意长度的密码输入。通过使用SHA,我们可以快速的将一些的确很长的密码转换为一个512比特的固定长度,解决了上述两个问题-即避免降低密码熵和预防DoS攻击[译者注:关于第一点,熵是信息学里面的一个概念,这里引入信息学中的信息熵(我们常听人说这个信息多、那个信息少,对信息“多少”的量化就是信息熵),用它来作为密码强度的评估标准。信息熵计算公式为 H = L * log 2 N,其中,L表示密码的长度,N是字符种类,密码强度 (H) 与密码长度 (L) 和密码包含字符的种类 (N) 这两个因素有关。也就是说密码包含的字符种类越多,密码长度越长,熵越大,更多细节参见这篇文章。由于一些bcrypt算法截断了用户密码为72个字节长度,从而导致超过72个字节的用户输入无效,一定程度降低了密码熵。而第二点是有文章提到如果不限制用户输入的密码长度,很容易遭到DoS攻击,比如django之前有个版本没有限制密码长度,而它用的又是PBKDF2哈希算法(PBKDF2是是一个CPU计算密集型算法,但是对GPU效果不如bcrypt,这里有个比较,这样如果攻击者输入的密码长度达到1M的话,对密码进行哈希需要几分钟的计算时间从而在大量这样的请求下导致服务器无法正常服务,这里使用SHA512先进行一次哈希的优缺点分析还可以参见这个帖子]

然后,对SHA512哈希后的值使用bcrypt算法再次哈希,使用的工作因子是10,每个用户都有一个单独的salt。不像其他的哈希算法比如SHA等,bcrypt算法很慢,它很难通过硬件和GPU加速。设置工作因子为10,在我们的服务器上执行一次bcrypt大概需要100毫秒。[译者注:使用python的bcrypt模块,默认的工作因子为12,在我的电脑上执行一次大概是300毫秒左右,而如果工作因子设置为20,这个时间大概为89秒]

最后,使用bcrypt哈希过后的结果再次使用AES256算法进行加密,使用的密钥是所有用户同意的,我们称之为pepper。pepper是我们基于深度考量的一种防御措施,pepper以一种攻击者难以发现的方式存储起来(比如不要放在数据库的表中)。由此,如果只是密码被拖库了,通过AES256加密过的哈希密码对于攻击者来说毫无用处。

为什么不用{scrypt,argon2}

我们也曾考虑过使用scrypt,但是我们对bcrypt有更多的经验。关于这几种算法那种更好的讨论一直都有,大部分的安全领域的专家都认为scrypt和bcrypt的安全性上相差无几。

我们考虑在下一次升级中使用argon2算法:因为在我们采用当前的方案的时候,argon2还没有赢得 Password Hashing Competition。此外,尽管我们认为argon2是非常棒的密码哈希函数,我们更倾向于采用bcrypt,因为从1999年以来,bcrypt还没有发现有任何重大的攻击存在。

为什么使用一个全局的密钥(pepper)替代哈希函数

如前面提到的,采用一个全局的密钥是我们深度权衡后的一个防御措施,而且,pepper我们是单独存储的。但是,单独存储pepper也意味着我们要考虑pepper泄露的可能性。如果我们只是用pepper对密码进行哈希,那么一旦pepper泄露,我们无法从哈希后的结果反解得到之前bcrypt哈希过的密码值。作为一个替代方案,我们使用了AES256加密算法。AES256算法提供了差不多的安全性,同时我们还可以反解回原来的值。尽管AES256这个加密函数的输入是随机的,我们还是额外加上了一个随机的初始化向量(IV)来增强安全性。

下一步,我们考虑将pepper存储到一个硬件安全模块(HSM),对我们来说,这虽然是一个相当复杂的任务,但是它能极大的降低pepper泄露的风险。同时,我们也计划在下一次升级中增强bcrypt的强度。

展望

我们相信使用SHA512,加上bcrypt和AES256是当前保护密码最稳妥和流行的方法之一。同时,所谓道高一尺魔高一丈。我们的密码哈希程序只是加固Dropbox的众多举措之一,我们还部署了额外的保护措施-比如针对暴力攻击者密码尝试次数的速度限制,验证码,以及其他一些方法等。如之前图片中所示,我们积极的在各个层级进行投入以确保安全。当然,也很期待能够听到诸位的高见。

译者注

总结一下这篇文章,说道的Dropbox的加密方法大致就是三点:其一,使用SHA512把明文密码哈希,既避免降低密码的熵,又能防止DoS攻击。其二,使用bcrypt二次哈希,工作因子为10,每个用户都有一个独立的salt。最后,使用一个全局密钥(pepper)通过AES256算法对二次哈希的值进行加密存储。

相关文章

  • [译]Dropbox是如何安全地存储用户密码的

    最初看到这篇文章是在 @登州知府 的微博上看到的,他的微博上分享了很多好的技术博客,推荐。由于本人英语学的比较烂,...

  • 如何安全地存储密码

    原文地址:http://blog.csdn.net/cadcisdhht/article/details/1928...

  • 《增长黑客》能给我们带来哪些启示?

    Dropbox(文件存储软件)用户推荐计划 用户每推荐一个朋友使用Dropbox的服务,就会额外给他们250兆的存...

  • 如何安全地保存用户的密码

    最近数据库泄漏事件层出不穷,无数人的上网密码被人破解。本文来探讨一下如何安全地保存用户的密码。为什么非要安全地保存...

  • Git Bash 记住用户名密码

    Git for windows (又名 msysgit)如何记住用户名和密码 : 先创建存储用户名密码的文件 ,在...

  • Dropbox 有哪些鲜为人知的使用技巧?

    Dropbox全球拥有五千万用户,因为这种巨大的普及,围绕Dropbox创建的基于在线存储服务的新的功能和扩展已经...

  • 《增长黑客》

    《增长黑客》 Dropbox是第一批为用户提供云盘存储服务的硅谷公司。在这第一批玩家的激烈竞争中,Dropbox的...

  • 如何安全地保存用户的密码?

    最烂的方式:明文保存 许多早期制作的网站,还有众多的政府网站,都是这么保存密码的,包括著名的CSDN也是。有的时候...

  • 增长黑客案例

    一、《增长黑客》文章案例: 1.dropbox(文件存储软件)用户推荐计划:用户推荐后额外送250M存储空间,对客...

  • 用户密码存储

    1 明码 2 转化为加密密码 如md5 但是通过密码表核对也能破解 3 加盐 在密码加上固定字符串再加密 4 禁止...

网友评论

  • 张达西::+1:
    尤其是译注那一部分,省去了翻原文的时间,多谢作者 :smile:
    __七把刀__:@张达西 客气:smile:
  • 6e661d7e21aa:有个地方翻大概译错了,我提出点我自己的看法,如果说的对,希望能采纳,如果说错了还请见笑:
    `但是,单独存储pepper也意味着我们要考虑pepper泄露的可能性。如果我们只是用pepper对密码进行哈希,那么一旦pepper泄露,我们无法从哈希后的结果反解得到之前bcrypt哈希过的密码值`
    这里前后因果错误,导致理解不能。原文的意思(在我看来)是没有因果的, `那么一旦pepper泄露` 这一句找不到对应的原文。原文这里确实比较模糊,只说了 `we can’t easily rotate it` ,而没说为何这样就放弃hash,你解释一下固然无妨。但我推测,从 `泄露的可能性` + `不能反解` 到放弃hash的方案,其中应该还有一环没说清楚。如果要我解释,我觉的是这样的:由于存在泄露的可能,所以在pepper泄露后,必须有能力将原密文(经过了sha512和bcrypt处理后的)反解,从而再采用更换pepper之类来进行补救,所以不能反解的hash方案被否决。
    __七把刀__:@正逍遥0716 太客气了:smile:
    6e661d7e21aa:@__七把刀__ 哪里哪里,你的翻译才要赞的,帮了我大忙了,给你6.66
    __七把刀__:恩,你的解释更加详细,赞。

本文标题:[译]Dropbox是如何安全地存储用户密码的

本文链接:https://www.haomeiwen.com/subject/vekayttx.html