远程存储密码保护私钥

remotely stored password protected private key

我想知道是否有这方面的协议。

想法是在服务器上有一些加密数据。

现在我想找到一个满足以下要求的协议。

  1. 由于主动管理密钥超出了大多数用户愿意忍受的范围,因此服务器上存储了受密码保护的密钥。

  2. 服务器应该无法解密数据。 IE。无法学习密码

  3. 第三方应该无法访问受密码保护的密钥,因为他们不知道密码。

  4. 密码应该只有一个。使用 2 个密码即可轻松解决该问题。一个用于下载受保护的密钥,一个用于取消保护密钥

解决方案可能涉及某种密码知识的零知识证明。

从同一个密码生成多个密钥和身份验证哈希没有问题。在任何情况下,您都不应该将真实密码发送到服务器。你想先通过 PBKDF2 发送它。我通常的身份验证建议如下所示:

salt = static-per-app-token + username
key = PBKDF2(salt, password, > 10000 iterations)
send key to server
on server: finalkey = SHA512(key) // This step keeps someone who steals your auth database from logging in
compare finalkey to database

鉴于该过程,您只需修改 PBKDF2 步骤即可根据需要生成两倍的密钥。前 X 个字节用于验证,后 X 个字节用于解密。 PKBDF2 可以创建任意多的字节,拥有一半的字节并不能帮助您计算出另一半。

对于您的具体问题,这可能是最方便且性能最好的方法。您也可以按照您的建议进行,并为 PBKDF2 使用两种不同的盐。那也可以。计算只需要两倍的时间。如果这不是问题,那么这是一个非常简单的解决方案,并且根据您的代码可能会更加方便。

但为了进一步讨论,假设您没有密码。你有一个(随机)密钥,你想从中创建独立的密钥。或者您已经有了 PBKDF2 的输出,并希望将其扩展为更多密钥。在这种情况下,您可以使用 HKDF 扩展键。过程很简单(|| 表示“连接”):

prk = psuedorandom key (your input key)
info = some-random-token || username
T(0) = empty string (zero length)
T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)    ...

您不断构建 T(n),直到您有足够的字节用于所有密钥。您将所有 T(n) 结果粘合在一起,然后将其切片以取出密钥。这比 PBKDF2 快得多,如果你愿意,可以应用于 PBKDF2 的输出。

查看 RNCryptor v4 spec 的示例,了解将单个密码扩展为一组不同的密钥和随机值的过程。

密码仍然很糟糕,none 这可以修复选择不当的密码,但如果密码相当难以猜到,那至少对你有利。