我想存储一些加密的数据,例如密码管理器,您的主密码可以解锁所有底层应用/网站密码。
环顾四周,我发现了一些例子,比如 this ,但他们似乎将密码用作加密的一部分,类似于散列中的盐。这意味着要解密您需要完全相同的密码,因此您永远无法更改密码。从安全/可用性的 Angular 来看,这似乎不太好;如果 PW 遭到破坏,您必须在不同的 PW 下重新制作整个数据库。
您将如何制作一个可以更改主密码的系统?您是否进行简单的登录检查,然后使用字符串进行加密/解密?静态性质加上该字符串的存储会不会不安全?
我知道一些 PHP 和一点点 Javascript,所以如果您有这些语言的示例会很好,但也非常感谢更一般的高级解释。
最佳答案
有几种有效的方法。 Jannes's answer暗示一个可行的解决方案(尽管提防 vulnerabilities in openssl_private_decrypt()
)。
如果您使用 Defuse Security's PHP encryption library ,受密码保护的 key 被抽象出来。 (目前有一个 open pull request 来解决使“更改密码”操作无缝且易于使用的问题。)
另请参阅:https://github.com/defuse/php-encryption/blob/master/docs/classes/KeyProtectedByPassword.md
How would you make a system where you can change the master password?
像这样:
- 生成一个强随 secret 钥。我们称之为
secret
。 - 从用户的主密码和静态盐(从加密安全随机数生成器生成一次)派生出一个单独的 key 。我们称之为
passwordKey
。Argon2id(密码, 盐)
=>passwordKey
- 使用带有随机数的安全 AEAD 模式,使用
passwordKey
加密secret
,并将结果与盐一起存储。$saved = $salt . $随机数。 sodium_crypto_secretbox($secret, $nonce, $passwordKey);
- 实际数据本身将使用
secret
加密,而不是passwordKey
。
如果您需要更改密码,只需使用新密码(和不同的盐)重复步骤 2 和 3。
对于 Argon2id,您可以在 PHP 7.2 及更高版本上使用 sodium_crypto_pwhash()
。
关于javascript - 更改用于加密的主密码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45233269/