I want to store some data encrypted, for example like a password manager where your master password unlocks all the underlying app/site passwords.
Looking around I found some examples like this, but they seem to use the password as a part of the encryption, similar to a salt in hashing. This means that to decrypt you need the exact same password, so you cannot ever change the password. This doesn't seem great from a security/usability standpoint; if a PW gets compromised, you'd have to remake the whole database under a different PW.
How would you make a system where you can change the master password? Do you you do a simple login check, and then use a string to encrypt/decrypt? Wouldn't the static nature plus storage of that string be unsafe?
I know some PHP and a smidge of Javascript, so if you have examples in those languages that would be nice, but a more general high level explanation is also very much appreciated.
Click the Security. Click Change Password. First, you'll need to enter your Current Master Password. After that, enter your New Master Password and confirm it.
Not only do password managers help securely house your passwords, but they can also generate passwords that are unique and complex, which makes them more difficult to crack or guess. To do this, password managers use encryption algorithms.
Cybersecurity experts recommend changing your password every three months. There may even be situations where you should change your password immediately, especially if a cybercriminal has access to your account.
There are a couple of approaches that work. Jannes's answer alludes to a workable solution (although beware of vulnerabilities in openssl_private_decrypt()
).
If you're using Defuse Security's PHP encryption library, password-protected keys are abstracted away. (There's currently an open pull request to tackle making "change password" operations seamless and easy-to-use.)
See also: 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?
Something like this:
secret
.passwordKey
.
Argon2id(password, salt)
=> passwordKey
secret
with the passwordKey
, using a secure AEAD mode with a random nonce, and store the result alongside the salt.
$saved = $salt . $nonce . sodium_crypto_secretbox($secret, $nonce, $passwordKey);
secret
, not passwordKey
.If you need to change the password, just repeats step 2 and 3 with the new password (and a different salt).
For Argon2id, you can use sodium_crypto_pwhash()
on PHP 7.2 and newer.
You could use public-key cryptography, using the public key to encrypt data and with a password in your private key, that can be changed.
One solution would be: 1) Generate rsa private and public keys (on Ubuntu):
openssl genrsa -des3 -out private.key 1024
openssl rsa -in private.key -pubout > public.key
2) Use the public key to encrypt:
$key = file_get_contents('/path/to/public.key');
openssl_public_encrypt("password", $encryptedData, $key);
Save $encryptedData to your database(you cannot use this string as password hash to match for login, as the $encryptedData have random bits added before encryption, you will still need to use a hash function for the passwords).
3) Use the private key to decrypt, providing the password:
$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) Change the password:
openssl rsa -des3 -in private.key -out private.key
This gives you 2 advantages:
This will serve your main requirement of being able to change the password and not re-encrypt the data.
If you want to further secure your private key(to not allow php to directly access your private key, which is useful in case your app is hacked), you can create a decrypt service in your system, that you can use to send the encrypted data with the password and get the decrypted data.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With