假设我有一个从N
个不同输入中获取密钥的方案。每个输入可能不是完全安全的(f.x.错误密码),但结合起来它们是安全的。执行此操作的简单方法是按顺序连接所有输入,并使用哈希作为结果。
现在我想允许在N-1
输入中只给出N
的密钥推导(或者更确切地说是密钥解密)。一种简单的方法是生成随机密钥K
,从输入的不同N
子集中生成N
个临时密钥,每个临时密钥丢失一个输入(即{{1} })然后使用每个Hash(input_{1}, ..., input_{N-1}), Hash(input_{0}, input_{2}, ..., input_{N-1}), Hash(input_{0}, input_{1}, input_{3},..., input_{N-1}), ..., Hash(input_{0}, ..., input_{N-2})
密钥加密K
并存储所有结果。
现在我想要一个通用的解决方案,我可以使用N
输出K
来解密密钥。扩展上述方案的天真方法需要存储(N
选择N
)值,这很快就会变得不可行。
是否有一个很好的算法,这不需要这么多的存储空间?
我已经考虑过使用像Shamir的秘密共享方案这样的方法,但由于输入是固定的,因此无法想到一个好方法。
答案 0 :(得分:1)
错误纠正代码是解决问题的最直接方法。但是,它们并不是特别容易实现的。
最好的方法是使用Reed Solomon Code。第一次导出密码时,还要计算代码所需的冗余并存储它。如果要重新计算密钥,请使用冗余来纠正错误或丢失的输入。
答案 1 :(得分:1)
加密/创建:
取N个输入。以良好/安全的方式将每个变成一个块。使用Reed Solomon从N块组合生成M个冗余块。您现在有N + M个块,其中您只需要总共N个来生成原始N个块。
使用N个块加密或创建安全密钥。
如果是第一个,则存储加密密钥和M个冗余块。如果是第二个,只存储M个冗余块。
解密/检索:
取N-R个正确的输入块,其中R =< M.将它们与您存储的冗余块组合以创建原始N块。使用原始N块来解密或创建安全密钥。
(感谢https://stackoverflow.com/users/492020/giacomo-verticale:这基本上是他/她所说的,但我认为更明确/更清楚。)
答案 2 :(得分:1)
Shamir's share secret是一种技术,当您想要在多个共享中拆分秘密时使用,这样只有最小k部分的组合才能揭示初始秘密。如果您不确定启动器的正确性,并且您想验证这一点,则使用verifiable secret sharing。两者都基于多项式插值
答案 3 :(得分:0)
一种方法是生成纯随机密钥(或者通过散列所有输入,如果由于某种原因想要避免使用RNG),使用k-of-n阈值方案将其拆分,并加密每个共享使用个人密码输入(例如,通过PBKDF2发送100000次迭代,然后使用AES-CTR / HMAC加密/ MAC)。这比存储哈希子集需要更少的存储空间;大致为N *(份额大小+盐大小+ MAC大小)
答案 4 :(得分:0)
除了简单地从大量输入中允许一些错误之外,您应该将输入分成组并在每个组中允许一些错误。如果您允许64个输入中的4个错误,那么您必须拥有15,249,024个加密密钥,但如果您将其分成两组32个,每组允许两个错误,那么您只需要拥有1984个加密密钥。 / p>
一旦您解密了每个组的密钥信息,然后将其用作您最终想要的解密密钥的输入。
此外,与您最终想要的密钥相比,从每个组获取的密钥不能是微不足道的。不要简单地将256位密钥分解为8个32位密钥块。这样做可以让那些可以解密其中7个关键部分的人尝试对最后一块进行暴力攻击。如果要访问256位密钥,则必须使用256位密钥进行整个过程。