更改用于加密的主密码

时间:2017-07-21 08:51:47

标签: javascript php security encryption password-encryption

我想存储一些加密的数据,例如密码管理器,其中您的主密码可以解锁所有底层的应用/网站密码。

环顾四周,我发现了一些像this这样的例子,但他们似乎使用密码作为加密的一部分,类似于哈希中的盐。这意味着要解密您需要完全相同的密码,因此您无法更改密码。从安全性/可用性的角度来看,这似乎并不是很好;如果PW受到损害,您必须在不同的PW下重新制作整个数据库。

您如何建立一个可以更改主密码的系统?您是否进行了简单的登录检查,然后使用字符串进行加密/解密?静态性质加上该字符串的存储不会不安全吗?

我知道一些PHP和一些Javascript,所以如果你有这些语言中的例子会很好,但更高级的解释也非常受欢迎。

3 个答案:

答案 0 :(得分:4)

有几种方法可行。 Jannes's answer提到了一个可行的解决方案(虽然提防vulnerabilities in openssl_private_decrypt())。

如果您正在使用Defuse Security's PHP encryption library,则会抽象出受密码保护的密钥。 (目前有open pull request来解决制作"更改密码"操作无缝且易于使用。)

另请参阅:https://github.com/defuse/php-encryption/blob/master/docs/classes/KeyProtectedByPassword.md

  

您如何建立一个可以更改主密码的系统?

这样的事情:

  1. 生成一个强大的随机密钥。我们称之为secret
  2. 从用户的主密码和静态盐(从加密安全随机数生成器生成一次)中获取单独的密钥。我们称之为passwordKey
    • Argon2id(password, salt) => passwordKey
  3. 使用secret加密passwordKey,使用带随机随机数的安全AEAD模式,并将结果与​​salt一起存储。
    • $saved = $salt . $nonce . sodium_crypto_secretbox($secret, $nonce, $passwordKey);
  4. 实际数据本身将使用secret加密,而不是passwordKey
  5. 如果您需要更改密码,只需使用新密码(以及不同的盐)重复步骤2和3。

    对于Argon2id,您可以在PHP 7.2及更高版本上使用sodium_crypto_pwhash()

答案 1 :(得分:1)

您可以使用公钥加密,使用公钥加密数据并使用私钥中的密码进行更改。

一种解决方案是: 1)生成rsa私钥和公钥(在Ubuntu上):

openssl genrsa -des3 -out private.key 1024
openssl rsa -in private.key -pubout > public.key

2)使用公钥加密:

$key = file_get_contents('/path/to/public.key');
openssl_public_encrypt("password", $encryptedData, $key);

将$ encryptedData保存到您的数据库(您不能使用此字符串作为密码哈希来匹配登录,因为$ encryptedData在加密之前添加了随机位,您仍然需要使用哈希函数作为密码)。

3)使用私钥解密,提供密码:

$key = openssl_pkey_get_private(file_get_contents('/path/to/private.key'), $password);

if($key === false) {
    // false password
    die;
}
openssl_private_decrypt($encryptedData, $decryptedData, $key);

4)更改密码:

openssl rsa -des3 -in private.key -out private.key

这为您提供了两个优势:

  • 单独加密&解密应用程序,加密不需要私钥或密码。
  • 密码不需要保存在应用程序中。

这将满足您更改密码而不重新加密数据的主要要求。

如果您想进一步保护您的私钥(不允许php直接访问您的私钥,这对您的应用被黑客攻击很有用),您可以在系统中创建一个解密服务,您可以使用使用密码发送加密数据并获取解密数据。

答案 2 :(得分:-1)

您是否考虑过使用GPG?

http://php.net/manual/en/ref.gnupg.php

或libsoduim PECL扩展

https://pecl.php.net/package/libsodium

使用久经考验的加密与滚动自己将会为您节省时间,但可以根据需要保护您的帐户