我们都应该知道关于密码强度的 XKCD 漫画,它(适当地)暗示基于多个常用词的密码比诸如Aw3s0m3s4u(3
或之类的密码更安全、更容易记住。
我有一个应用程序(多平台),我想为其生成一些安全的密码,而且我的密码要求要低得多:如果密码没有空格,我希望“多个符号、数字、混合 alpha 和 6+ 个字符” ,但如果密码有多个不连续的空格,我将放宽符号/数字/混合大小写限制,而是要求至少两个单词分别不少于 4 个字符,密码长度至少为 15 个字符。
问题不在于这方面,而是关于生成:假设我想为用户生成一个易于记忆且难以猜测的密码,基于 5 个左右的字典单词生成密码在密码学上是否安全从 10k 单词列表中?(从字面上看,我的数据库中有 10k 个单词,从各种来源、电子邮件等中抓取。)它们都是非常常见的单词,长度不少于 3 个字符。
现在我不想制作这些一次性密码,但我怀疑我至少应该要求用户在使用这个生成的密码后登录时将其更改为其他密码,这很好,我可以,但我还希望用户可以选择(在更改密码时)生成符合我要求的“安全”密码。
从破解的角度来看,攻击使用此方案生成的密码有多容易/多难?没有固定长度,这个数据库表中的单词长度从3个字符到11个字符(environment
例如数据库中的一个单词)?生成密码的程序不会选择 4 个或更少字符的两个单词(因此最短的密码可以是 1 个三字符单词、4 个五字符单词和 4 个空格,总共 27 个字符),它不会在密码中使用相同的术语两次。
根据我针对它运行的示例,程序生成的平均密码长度约为 34 个字符,这对我来说似乎可以接受。即使我们假设最少 27 个非空格字符(最后是 23 个字符)中的每一个都可以是 26 种可能的状态(a-z
),那是23^26
或2.54e+35
可能性。
数据库中有 994 个词,长度为 3 到 4 个字符。
我们还可以假设攻击者拥有字典和生成参数/算法。这仍然安全吗,我可以从生成的密码中删除一个单词(仍然是 21 个字符,仅基于熵的18^26
可能性(4.33e+32
)),我看到的唯一问题是这不是基于字符熵,但是在单词熵上,这意味着 5 字密码是10000*9006*9005*9004*9003
可能性,或6.5e+19
可能性,而 4 字密码是10000*9006*9005*9004
可能性,或7.30e+15
. 与普通的 6 字符密码((26+26+10+33)^6
或7.35e+11
可能性:26
小写字母、26
大写字母、10
数字、33
符号)相比,它要强得多。
我做了另一个假设:用户会写下来,他们总是这样做。我怀疑一张纸上的五个随机单词(希望不是直接看到,但唉,这是最有可能的情况)不太可能被选为潜在的密码,而不是看起来像传统的复杂术语密码。
最后,在我回答实际问题之前,密码在存储到数据库之前都经过加盐处理,然后用SHA-512
算法进行 100 次散列,每个散列之间附加加盐。如果用户成功登录,则更改 salt 并创建新的密码哈希。(我认为这对暴力离线攻击没有多大帮助,但它应该有助于抵御我认为的主动在线攻击。)
DatabasePassword = SHA512(...SHA512(SHA512(SHA512(password + salt) + salt) + salt) + salt)...)
所以,最后,我的实际问题:
- 我的数学正确吗?(您不必一定要回答这个问题,我相信它在原则上足以证明我的担忧。)
- 这一代是安全的还是我应该坚持使用“传统”密码生成?请注意,攻击者不知道用户的密码是使用此算法生成的还是由用户选择的,如果他们知道长度,攻击者可以做出假设,但这可能是安全的,也可能不是.
- 最后,我是否做出任何会显着改变(增加或减少)这个“想法”的安全性的假设?(例如,假设 6 个字符的密码的每个字符的熵是 95。)
为篇幅道歉,我习惯于过度解释自己以希望减轻困惑。
有人指出我的问题与这个问题非常相似,我想指出我的生成方法的差异(但老实说,它仍然足够相似,可以被认为是重复的,我把它留给社区决定):
- 每个单词都用空格分隔,这意味着除了第一个和最后三个字符之外的所有字符都具有额外的潜在状态。
- 密码不是由人选择的,它(大部分)是统一随机生成的。除了只允许一个超短(3 或 4 个字符)单词之外,没有任何单词比其他单词更受欢迎,一旦随机生成器选择了该长度的单词,就不能再选择这些单词了。(虽然该单词在单词列表中的位置仍然是随机的,可能不会选择一个超短单词。)
- 这与单独的密码限制混合在一起,这意味着攻击者有两个向量可以尝试破解。用户可以选择满足“传统”要求的密码或满足“XKCD”要求的密码。