安全与隐私codahale.com
如何安全地存储密码
How To Safely Store A Password
2010 — 2020,它一次次回到首页
黑点是上首页(≥ 50 分)的那次投稿,空心点是没冲上去的投稿,点越大分数越高。
导读
这篇文章讲如何安全地存储用户密码:普通加盐哈希只能防彩虹表,挡不住针对单个密码的字典或暴力猜测;应使用 bcrypt 这类自适应哈希,通过可调工作因子故意让每次计算变慢。文章还讨论了盐的作用边界,以及算法和工作因子随硬件进步调整的问题。核心结论是:密码哈希的安全性来自计算成本,而不只是加盐。
为什么经久不衰:它把“加盐哈希并不等于安全”讲得足够清楚,并给出 bcrypt 这一可落地答案,所以十几年后仍被反复贴到 Hacker News。
HN 评论精选
批评主流安全文章遗漏 bcrypt,并给出若干不靠谱建议,说明正确做法仍不普及。
很多开发者都需要读懂这篇文章,这远不是主流常识……前几天我在 RSS 里看到 SANS 一篇讲密码哈希的文章:没提 bcrypt(虽然提到用 SHA1 做密钥拉伸);说改算法后只能让用户改密码(其实下次登录时就能更新);建议在数据库外再加一个秘密(这是 security through obscurity);甚至建议在客户端用 JavaScript 做哈希。这个博客据 Google Reader 约有 1.5 万订阅者。
eneveu查看英文原文
Many developers need to read and understand this. It is far from mainstream knowledge... The other day, I saw the following post about password hashing in my RSS feed: http://isc.sans.org/diary.html?storyid=11110 - No mention of bcrypt (though the posts mentions key stretching using SHA1) - "When selecting an algorithm to hash passwords, it is important to select carefully as it is difficult to change the algorithm later. You will have to ask users to change their password if you do as you no longer know what password they picked." --> seriously? you can update the password the next time they log in... - "You could also add a secret, in addition to the salt. If the secret is not stored in the database, it would not be easily reachable via a SQL injection exploit (yes, you can use them to read files, but it requires sufficient privileges)." --> security through obscurity, nice - "For the paranoid, you may want to do the hashing on the client side (javascript) . This way, the server never receives the plain text password. We do this here for the ISC website on our login form [2]." --> oh noes... Note that the blog has ~15k subscribers according to Google Reader... --------- I also launched a debate on StackOverflow the other day. A self-proclaimed "security expert" (he later edited his post to remove this part) was advising against using bcrypt, arguing that it would facilitate DOS attacks against the login page... He prefers security through obscurity, using a secret salt: http://security.stackexchange.com/questions/4781/do-any-security-experts-recommend-bcrypt-for-password-storage/4782#4782 I thought it was a bad idea to leave this answer unchallenged, so I tried arguing with him. I was met with arguments of authority such as "Wow you are out of your element and could not be more misguided on this topic" or "you disagree because you don't understand. Show me an exploit you have written, then I'll pay attention to you.". Happily, some (more experienced) people got in on the debate. I hope this will help developers make an informed choice, if they stumble upon his answer... (edit: list formatting)
指出自适应哈希工作因子升级与旧密码兼容性的疑问。
我读了本文和 Wikipedia 的 bcrypt 条目,仍不明白:文中说计算机变快后可以提高工作因子、让哈希变慢;但提高速度后,怎么还能验证之前存下的密码?谁能解释一下?
Khao查看英文原文
I have read this article and read the Wikipedia entry on bcrypt and I still cannot understand something. In this article it states that : "As computers get faster you can increase the work factor and the hash will get slower.". How can you make the algorithm slower over time and still be able to validate user passwords that were stored before you changed the speed? Could anyone enlighten me on this?
介绍用迭代哈希做密钥拉伸的思路及其与服务器延迟的权衡。
bcrypt 和 scrypt 是很好的库。不过穷人的办法是:用你喜欢的哈希函数,先 update(password)、再 update(salt),然后循环 X 次 update(HASH.digest()),最后返回 digest。这样反复计算来增强哈希;X 就是轮数,也就是你愿意让服务器对单次请求慢到什么程度,目标是把字典攻击拖到不可行。注意每个密码都要用不同的盐。
timtadh查看英文原文
B-crypt and S-crypt are great libraries to use to solve this problem. However, the poor man's approach is as follows with HASH being your favorite hash function h = HASH.new() HASH.update(password) HASH.update(salt) for x in xrange(X): HASH.update(HASH.digest()) return HASH.digest() this approach "strengths" the hash by forcing you to calculate it over and over again. You should set X to be the number of rounds you want to conduct. Ie. how slow you want you server to respond to an individual request. It is always a trade-off between server slowness for individual requests and "security" of the hash function. The goal is to make dictionary attacks take longer than is feasible for you attackers to conduct. [Note: you should absolutely have a different salt for each password with this approach.]
指出 bcrypt 已被 Rails 3.1 的 SecurePassword 采用。
看起来 Rails 3.1 正在使用 bcrypt:https://github.com/rails/rails/blob/master/activemodel/lib/active_model/secure_password.rb
stephth查看英文原文
Looks like Rails 3.1 is using bcrypt: https://github.com/rails/rails/blob/master/activemodel/lib/active_model/secure_password.rb
历次讨论
同类还值得读
非法素数
Illegal prime
维基百科条目,介绍“非法素数”:某些素数之所以被称为“非法”,是因为它们经特定编码后,恰好对应一段被法律禁止传播的数据——最著名的是 DVD 解密程序 DeCSS 的代码,有人把…
安全与隐私上首页 5 次 · 2010–2021en.wikipedia.org编辑精选关于 /dev/urandom 的常见误区
Myths about /dev/urandom
(Thomas Hühn 撰写,2014 年首发并持续更新)逐条反驳关于 /dev/urandom 的常见误解:它与 /dev/random 使用的是同一个 CSPRNG,一旦完…
安全与隐私上首页 5 次 · 2014–20202uo.de编辑精选AES 高级加密标准火柴人图解
A Stick Figure Guide to the Advanced Encryption Standard (AES)
一篇用火柴人漫画形式讲解 AES(高级加密标准)算法的经典科普文章。
安全与隐私上首页 5 次 · 2009–2022moserware.com编辑精选指纹是用户名,不是密码
Fingerprints are Usernames, not Passwords
作者(eCryptfs 维护者、Ubuntu 安全工程师)认为指纹等生物特征是公开、不可更改的标识,应视作用户名而非密码,不能当作秘密凭据用于认证。
安全与隐私上首页 4 次 · 2013–2017blog.dustinkirkland.comHTTPS 连接的最初几毫秒(2009)
The First Few Milliseconds of an HTTPS Connection (2009)
逐毫秒拆解一次 HTTPS 连接建立时发生了什么,重点讲 TLS 握手、证书验证、RSA 签名与密钥协商等机制,面向不熟悉该领域的读者。
安全与隐私上首页 4 次 · 2009–2020moserware.com编辑精选