macosX钥匙串上本机难忘密码的熵

信息安全 苹果系统 钥匙链
2021-09-03 12:38:26

我一直在努力寻找这方面的信息。但是我没有在网上找到任何东西。

当您在 mac 上使用密码管理器时,它可以提供“难忘”的密码。

例如pick3"enigma. (您选择字符数)

我没有找到任何信息,说明使用的是什么字典,使用了哪些额外字符和数字选项,以及它们如何全部固定以获得您建议的字符数量......因此,我无法确定此类密码的总熵。

是否有任何地方可以找到它可以使用的单词范围以及可能性,以了解这些密码提供的总熵是多少?

或者提供一些可靠信息的来源,说明钥匙串创建的“记忆密码”的熵是多少

2个回答

Anders Bergh 对 OS X 密码助手进行了逆向工程,并编写了一个命令行实用程序来完成相同的工作。它的来源可以发现,所有的密码生成的由专用的无证库函数完成SFPWAPasswordSuggest()SecurityFoundation框架

尽管该函数是专有的并且不存在官方的 Apple 文档,但您可以使用该函数本身或围绕它的命令行实用程序来确定它正在生成什么。Allister Banks在 2015 年就已经这样做了,假设是针对 OS X Yosemite,并提出了一个产生几乎相同结果的代码片段(除了一些奇怪的作者偏好,比如限制可用随机数的范围)。

简而言之,SFPWAPasswordSuggest()从词汇表中选择两个随机单词,并在它们之间插入一个随机数和一个特殊字符(按此顺序)。随机数长度使得整个字符串长度完全符合要求,并且总是有一个特殊字符。关于词汇,从 Yosemite 到 High Sierra 的 OS X 使用/System/Library/Frameworks/SecurityInterface.framework/Resources/pwa_dict_en.gz287 kb 的大小和 83935 个长度在 2 到 24 之间的英语单词,为此:

$ gzcat pwa_dict_en.gz | python2 -c 'import sys
> sys.stdin.read(512)
> word_counts = dict()
> for num_of_letters_index in range(64):
>     value = int(sys.stdin.read(8).strip(), 16)
>     if value:
>         word_counts[num_of_letters_index] = value
> print "Distribution:", word_counts'
Distribution: {1: 26, 2: 191, 3: 1229, 4: 3170, 5: 5591, 6: 8913, 7: 12452, 8: 13462, 9: 12163, 10: 9820, 11: 7007, 12: 4516, 13: 2704, 14: 1429, 15: 691, 16: 329, 17: 150, 18: 61, 19: 21, 20: 5, 21: 3, 22: 1, 24: 1}
$

在此处输入图像描述

以下是解析文件的方法在其他 OS X 版本中,该功能的设计可能有所不同;使用dtruss ./sf-pwgen弄清楚。

请注意,GUI 将生成的密码长度限制为 31。据我所知,该函数不会对较长的请求产生错误,但不能保证对超过 31 个字符的密码有效。实际上,对于超过 67 个字符的密码,几乎可以保证失败;正如您在词汇表上方看到的那样,没有足够长度的单词,并且生成算法不能很好地处理这种情况,只需返回一个仅包含数字和特殊字符的短密码:

$ ./sf-pwgen -c 1 -l 68
2814154076!
$

编辑 24.01.2018:代表Alex Recuenco

计算熵

遵循@ximaera 解决方案。

import math

x = {1: 26, 2: 191, 3: 1229, 4: 3170, 5: 5591, 6: 8913, 7: 12452, 8: 13462, 9: 12163, 10: 9820, 11: 7007, 12: 4516, 13: 2704, 14: 1429, 15: 691, 16: 329, 17: 150, 18: 61, 19: 21, 20: 5, 21: 3, 22: 1, 24: 1}

def entropy(pass_length, n_symbols = 30):
    combinations = 0
    for key, value in x.items():
        for key2, value2 in x.items():
            if (key + key2) < (pass_length - 1):
                combinations += value * value2 * n_symbols * (10 ** (pass_length - key - key2 - 1))
                # last value

    return {'combinations': combinations, 'entropy': math.log2(combinations)}

print(entropy(31))

当你运行它时:

> {'combinations': 1124445877165765109161692550890600, 'entropy': 109.79284135298234}

最大 110 位熵...我认为出于某种原因会更好。仅包含长度为 30 的数字字符的密码的熵约为 100

用 zxcvbn 估计熵

估计密码熵的上限的一种合理方法,您不知道其生成方法是将其提供给zxcvbn 密码强度计,它有一个在线演示(我刚刚链接)并且相当复杂。因为pick3"enigma我们得到:

password:              pick3"enigma
guesses_log10:         8.28991
score:                 3 / 4
function runtime (ms): 1

guess times:
100 / hour:            centuries (throttled online attack)
10  / second:          7 months (unthrottled online attack)
10k / second:          5 hours (offline attack, slow hash, many cores)
10B / second:          less than a second (offline attack, fast hash, many cores)

match sequence:

'pick'
pattern:              dictionary    
guesses_log10:        2.56585   
dictionary_name:      us_tv_and_film    
rank:                 368   
reversed:             false 
base-guesses:         368   
uppercase-variations: 1 
l33t-variations:      1

'3"'    
pattern:              bruteforce    
guesses_log10:        2

'enigma'
pattern:              dictionary
guesses_log10:        2.63347
dictionary_name:      passwords
rank:                 430   
reversed:             false
base-guesses:         430
uppercase-variations: 1
l33t-variations:      1

guesses_log10字段可用于通过转换为基数 2(乘以 3.3)并加一来计算熵。因此,密码的熵不应超过 28.5 位。如上面的输出转储所示,该词pick在 zxcvbn 的us_tv_and_film字典中为 #368,enigma在其passwords字典中(常用密码)为 #430 ,因此离线攻击者可以在相当短的时间内猜出密码,而无需非常熟悉密码生成内部,只是关于人们如何经常选择密码的一般知识。

从字典大小和算法估计熵

另一种方法:@ximaera 的回答说密码是这样生成的,使用 83,935 个单词的字典:

简而言之,SFPWAPasswordSuggest() 从词汇表中挑选两个随机词,并在它们之间插入一个随机数和一个特殊字符(按此顺序)。

一组 83,935 个随机词比 16 位熵多一点。从 0 到 9 的一个数字大约是 3.3 位。一个 ASCII 非字母数字字符(共 33 个)约为 5 位。如果这是对生成器算法的全部解释,那么这将给我们大约 41 位。

但正如@ximaera 指出的那样,这还不是全部,因为生成器还具有限制密码字符长度的逻辑,显然是通过拒绝不等于用户请求长度的候选密码。所以实际上计算精确的熵是相当复杂的。太复杂了,我想说,因为上面更简单的计算已经告诉我们它必须小于 41 位,而且可能少得多。无论如何,这不是一个精确的数字,但它与 zxcvbn 估计的 28.5 位大致一致。

结论

生成的密码不是很强大,至少不是那个长度。如果我们将 64 位(例如,Diceware五字密码)视为我们应该使用的最低密码强度,那么这个 Apple 生成器远远不够。正如 zxcvbn 所展示的,一个老练的攻击者甚至不需要确切地知道算法是如何工作的。