From 6fa9f0839e30e5fdef652efcbbb4bd6bc8e5222c Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Sun, 3 Aug 2025 17:53:42 -0400 Subject: [PATCH] Fix legacy decryption iterations --- src/seedpass/core/encryption.py | 4 +++- src/tests/test_decrypt_data_legacy_fallback.py | 17 ++++++++++------- src/tests/test_nostr_legacy_decrypt_fallback.py | 17 ++++++++++------- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/seedpass/core/encryption.py b/src/seedpass/core/encryption.py index 4599699..66c1e97 100644 --- a/src/seedpass/core/encryption.py +++ b/src/seedpass/core/encryption.py @@ -138,7 +138,9 @@ class EncryptionManager: password = prompt_existing_password( "Enter your master password for legacy decryption: " ) - legacy_key = _derive_legacy_key_from_password(password) + legacy_key = _derive_legacy_key_from_password( + password, iterations=50_000 + ) legacy_mgr = EncryptionManager(legacy_key, self.fingerprint_dir) result = legacy_mgr.decrypt_data(encrypted_data) logger.warning( diff --git a/src/tests/test_decrypt_data_legacy_fallback.py b/src/tests/test_decrypt_data_legacy_fallback.py index ab90cde..e5019bd 100644 --- a/src/tests/test_decrypt_data_legacy_fallback.py +++ b/src/tests/test_decrypt_data_legacy_fallback.py @@ -8,13 +8,15 @@ from seedpass.core.encryption import EncryptionManager from utils.key_derivation import derive_key_from_password -def _fast_legacy_key(password: str, iterations: int = 100_000) -> bytes: - normalized = unicodedata.normalize("NFKD", password).strip().encode("utf-8") - key = hashlib.pbkdf2_hmac("sha256", normalized, b"", 1, dklen=32) - return base64.urlsafe_b64encode(key) - - def test_decrypt_data_password_fallback(tmp_path, monkeypatch): + calls: list[int] = [] + + def _fast_legacy_key(password: str, iterations: int = 100_000) -> bytes: + calls.append(iterations) + normalized = unicodedata.normalize("NFKD", password).strip().encode("utf-8") + key = hashlib.pbkdf2_hmac("sha256", normalized, b"", 1, dklen=32) + return base64.urlsafe_b64encode(key) + monkeypatch.setattr( enc_module, "_derive_legacy_key_from_password", _fast_legacy_key ) @@ -22,7 +24,7 @@ def test_decrypt_data_password_fallback(tmp_path, monkeypatch): enc_module, "prompt_existing_password", lambda *_a, **_k: TEST_PASSWORD ) - legacy_key = _fast_legacy_key(TEST_PASSWORD) + legacy_key = _fast_legacy_key(TEST_PASSWORD, iterations=50_000) legacy_mgr = EncryptionManager(legacy_key, tmp_path) payload = legacy_mgr.encrypt_data(b"secret") @@ -30,3 +32,4 @@ def test_decrypt_data_password_fallback(tmp_path, monkeypatch): new_mgr = EncryptionManager(new_key, tmp_path) assert new_mgr.decrypt_data(payload) == b"secret" + assert calls == [50_000, 50_000] diff --git a/src/tests/test_nostr_legacy_decrypt_fallback.py b/src/tests/test_nostr_legacy_decrypt_fallback.py index ef9d4b6..c130230 100644 --- a/src/tests/test_nostr_legacy_decrypt_fallback.py +++ b/src/tests/test_nostr_legacy_decrypt_fallback.py @@ -9,13 +9,15 @@ from helpers import create_vault, TEST_PASSWORD import seedpass.core.encryption as enc_module -def _fast_legacy_key(password: str, iterations: int = 100_000) -> bytes: - normalized = unicodedata.normalize("NFKD", password).strip().encode("utf-8") - key = hashlib.pbkdf2_hmac("sha256", normalized, b"", 1, dklen=32) - return base64.urlsafe_b64encode(key) - - def test_legacy_password_only_fallback(monkeypatch, tmp_path, caplog): + calls: list[int] = [] + + def _fast_legacy_key(password: str, iterations: int = 100_000) -> bytes: + calls.append(iterations) + normalized = unicodedata.normalize("NFKD", password).strip().encode("utf-8") + key = hashlib.pbkdf2_hmac("sha256", normalized, b"", 1, dklen=32) + return base64.urlsafe_b64encode(key) + # Speed up legacy key derivation monkeypatch.setattr( enc_module, "_derive_legacy_key_from_password", _fast_legacy_key @@ -26,10 +28,11 @@ def test_legacy_password_only_fallback(monkeypatch, tmp_path, caplog): vault, enc_mgr = create_vault(tmp_path) data = {"schema_version": 4, "entries": {}} - legacy_key = _fast_legacy_key(TEST_PASSWORD) + legacy_key = _fast_legacy_key(TEST_PASSWORD, iterations=50_000) encrypted = Fernet(legacy_key).encrypt(json.dumps(data).encode()) caplog.set_level(logging.WARNING) assert enc_mgr.decrypt_and_save_index_from_nostr(encrypted) assert vault.load_index() == data assert any("legacy password-only" in rec.message for rec in caplog.records) + assert calls == [50_000, 50_000]