tari-project / tari

The Tari protocol
https://tari.com
BSD 3-Clause "New" or "Revised" License
356 stars 220 forks source link

Add versioning to PBKDF applications #5151

Closed AaronFeickert closed 1 year ago

AaronFeickert commented 1 year ago

The codebase uses Argon2 as a password-based key derivation function (PBKDF). Specifically, it uses OWASP recommendations for its parameters, which are updated from time to time in order to reflect evolving threats from more advanced hardware. In fact, these parameters were recently updated.

Based on the current implementation, some future codebase updates to reflect parameter changes will be brittle, as there is currently no straightforward way to detect which parameters were used to generate any particular keys in applications not using the PHC string format. There should always be backwards compatibility for keys generated using older parameters, but users should (to the extent possible) always receive the safety and security benefits of the most recent parameters in use.

The best and most standard approach is to use versioning wherever a PBKDF is used, where a hardcoded version is stored or otherwise encoded such that the client uses the correct parameters for key derivation. It may important to bind this version to authenticated data in order to mitigate risks associated with version mismatches or downgrade attacks.

AaronFeickert commented 1 year ago

The codebase uses Argon2 in the following places:

AaronFeickert commented 1 year ago

Relating to this issue, we can simplify database encryption while supporting straightforward passphrase changes and upgrades.

Right now, database entries are encrypted using a key derived directly from the user's passphrase using the Argon2 PBKDF. This doesn't pose any particular security issues (aside from the ever-present risk of a weak passphrase, which we try to mitigate), but it makes it a pain to change the passphrase or upgrade the hashing parameters.

A way to make life a bit easier is to instead use a high-entropy random main key for encrypting database entries, and encrypt this key using a secondary key derived from the user's passphrase. When the user wishes to change their passphrase or upgrade to a newer version, we simply re-encrypt the main key using a newly-derived secondary key.

This has a second advantage, in that the use of authenticated encryption for this process allows for an easy check for the correct passphrase without needing to store a passphrase hash or test other database fields. It is still possible to store such a hash for versioning purposes, if this is more straightforward than storing a separate version identifier.

CjS77 commented 1 year ago

Great suggestion

AaronFeickert commented 1 year ago

Closing this issue.