diff options
| author | Osmium Sorcerer <os@sof.beauty> | 2026-09-23 16:47:29 +0000 |
|---|---|---|
| committer | Osmium Sorcerer <os@sof.beauty> | 2026-09-23 16:47:29 +0000 |
| commit | 99d36f45c05142194b6698f71d94281c4cd68bfe (patch) | |
| tree | b5dfa21f0f94fe23b0b796dbf672932387991c66 /src | |
| parent | 1e4319d7b9208d2ccb105c8a3853ecf97f600e4c (diff) | |
keyring: Improve key passphrase parameters
Change Argon2id parameters from 1 gigabyte of memory and 3 iterations
to 2 gigabytes and 2 iterations. Memory cost is the primary parameter
that provides substantial hardening, and 2 GiB in particular is
recommended by RFC 9106 (here with an additional iteration). This will
impact performance of key derivation on devices with constrained RAM,
but platform-backed keys should provide an alternative.
Enforce minimum of 6 characters for the passphrase. This is still not
enough considering an adversary can make unlimited offline guesses,
even with significant slowdown. However, this is consistent with
modern practices for authenticator policies (recommended, for example,
by NIST SP 800-63B-4): enforce minimal length and nothing else.
Diffstat (limited to 'src')
| -rw-r--r-- | src/keyring.cpp | 6 | ||||
| -rw-r--r-- | src/widgets/key_generate_dialog.cpp | 6 |
2 files changed, 7 insertions, 5 deletions
diff --git a/src/keyring.cpp b/src/keyring.cpp index 8f49dfa..4e8eeff 100644 --- a/src/keyring.cpp +++ b/src/keyring.cpp @@ -91,15 +91,15 @@ int generate_key(QStringView name, const QByteArray &password) } // Key wrapping. The crypto_pwhash derives the key from password with the - // specified parameters (3 iterations over 1 gigabyte of memory). This + // specified parameters (2 iterations over 2 gigabytes of memory). This // operation is slow and should ideally be handled asynchronously without // blocking the GUI thread. quint8 wrap_key[crypto_aead_chacha20poly1305_KEYBYTES]; sodium_mlock(wrap_key, sizeof(wrap_key)); quint8 salt[crypto_pwhash_SALTBYTES]; randombytes_buf(salt, sizeof(salt)); - quint32 pwhash_opslimit = crypto_pwhash_OPSLIMIT_MODERATE; - quint32 pwhash_memlimit = crypto_pwhash_MEMLIMIT_SENSITIVE; + quint32 pwhash_opslimit = 2u; + quint32 pwhash_memlimit = 2 * 1024 * 1024 * 1024u; quint8 pwhash_alg = crypto_pwhash_ALG_DEFAULT; if (crypto_pwhash(wrap_key, sizeof(wrap_key), password.constData(), password.size(), salt, pwhash_opslimit, pwhash_memlimit, pwhash_alg)) { diff --git a/src/widgets/key_generate_dialog.cpp b/src/widgets/key_generate_dialog.cpp index 1e9790e..72ba8a2 100644 --- a/src/widgets/key_generate_dialog.cpp +++ b/src/widgets/key_generate_dialog.cpp @@ -36,10 +36,12 @@ KeyGenerateDialog::KeyGenerateDialog(QWidget *parent) validate(); } -// Empty passwords should be also checked. void KeyGenerateDialog::validate() { - ui_key_gen_buttons->button(QDialogButtonBox::Ok)->setEnabled(!ui_key_password->text().isEmpty() && (ui_key_password->text() == ui_key_password_confirm->text())); + bool valid = !ui_key_password->text().isEmpty() && + (ui_key_password->text().length() >= 6) && + (ui_key_password->text() == ui_key_password_confirm->text()); + ui_key_gen_buttons->button(QDialogButtonBox::Ok)->setEnabled(valid); } QStringView KeyGenerateDialog::key_name() |
