我想知道使用类似scrypt或bcrypt“增强”保护 PGP 私钥的密码的一些语义和安全含义。本质上,我问的是使用scrypt密码作为我的 PGP 私钥密码的含义。
据我了解,一个 PGP 密钥对本质上只是两个大素数及其乘积,而私钥是对称加密的。
我目前的想法是,这是一个非常好的主意,主要有两个原因。首先,这使您的密码不易受到字典攻击,因为输出scrypt极不可能是字典单词(您可以检查它)。
第二个也是更复杂的原因是蛮力尝试所需的计算能力。
让我们假设检查存储在私钥中的(解密的)素数的单一猜测的成本是A。假设,给定一个泄露的加密私钥,检查一次猜测的成本是B。假设计算成本scrypt为C。
暴力破解 2048 位素数最多将花费 ,pi(2^2048) * A其中pi(x)素数的数量小于x。假设私钥被泄露,并假设 20 个字符(160 位)密码的上限并非不合理,暴力破解密码的最大成本为2^160 * B. 假设一个被泄露的密钥的密码已知是N-character ( N*8bit)的结果scrypt,暴力破解密码的最大成本是2^160 * C * BOR 2^(N*8) * B(因为攻击者可以尝试使用scrypt或只是破解哈希本身)。
请注意,使用标准估计器,pi(2^2048) ~= 2.28*10^613.
让我们为计算的目的进行修复A = 1,我们将假设 B >= 2考虑到整数乘法的低成本,这似乎是合理的。
,scrypt是C可变的。如果我们考虑C = 10(计算scrypt比将两个大数相乘困难 10 倍),那么:
- 暴力破解密钥的成本:
2.28*10^613 - 暴力破解密码的成本:
2^160 * 10 * 2 = 2.9 * 10^49或2^(N*8) * 2 = 2^(8N +1)
这里,2^(8N +1) = 2.9 * 10^49at around N = 21,这意味着如果C = 10,你只需要一个 21 个字符的散列就可以比散列更容易破解输入到散列。当然,拥有私钥本身仍然是有益的。
然而,scrypt有不同的难度,10可能是一个超级保守的估计。如果我们改为修复N = 128:
- 暴力破解密钥的成本:
2.28 * 10^6131 - 暴力破解密码的成本:
2^160 * C * 2或2^1024 * 2
这里,2^160 * C * 2 = 2^1024 * 2在 around C = 1.23 * 10^200,这显然是完全不合理的。这意味着,对于合理的散列长度,破解散列的输入可能总是比散列本身更好。
显然,如果我使用 的值N = 256,那么只要C > 1,实际上破解密钥比破解哈希更容易。
我认为假设是合理的C >= 1000。有了这个假设,修复N=256,并假设我们的密码是P字符:
- 暴力破解密钥的成本:
2.28 * 10^6131 - 暴力破解密码的成本:
2^(8P) * 1000 * 2或2^2048 * 2
人们需要P = 255使破解密码比破解密钥更难,这似乎不合理。
因此,似乎使用像scryptor这样的强硬哈希函数bcrypt可以大大提高猜键难度,即使对它们的强硬性进行保守估计也是如此。在密钥泄露的情况下,散列密码似乎也有帮助,但不是那么多。
我还有其他需要考虑的问题吗?我目前正在考虑一种“双密码”方法,其中密钥密码是passphrase + hash(another passphrase). 这似乎可以减轻使用我可能忽略的哈希结果加密素数的任何奇怪的数学特性。
编辑:只是先发制人,我不是(完全)白痴。我知道 PGP 定义了它自己的散列机制,S2K但是几乎没有人使用散列的“好”版本(默认情况下不启用),它缺乏良好的可配置性,并且很容易破解GPU 等加速器。所以,是的,我在这里在一定程度上建议“双重哈希”——但scrypt使用带有预设数据的特定哈希和抓取方法,并S2K使用好的 ol' 时尚指数和位方法。如果我记得我的密码学课程,那么只要一个函数的输出在另一个函数的域内(在这种情况下,它是),组合函数就没有问题。