mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2026-10-31 09:52:03 +00:00
Fix weak key derivation by adding salt to parent seed encryption
Introduced a random salt to key derivation for parent seed encryption to prevent rainbow table attacks. The salt is now stored in the `parent_seed.enc` file header (V3 format). * Modified `src/utils/key_derivation.py` to accept optional `salt` argument. * Modified `src/seedpass/core/encryption.py` to read/write salt in `parent_seed.enc` using V3 format (V3:salt:nonce:ciphertext). * Modified `src/seedpass/core/manager.py` to generate salt for new seeds and read salt for existing ones. * Added auto-upgrade logic for legacy (no salt) seeds upon access. * Updated tests to verify salt usage and backward compatibility. Co-authored-by: PR0M3TH3AN <[email protected]>
This commit is contained in:
1 parent
335de7abe3
commit
75fe5bc382
4 files changed
+118
-27
No files matched your search
@@ -45,7 +45,9 @@ DEFAULT_ENCRYPTION_MODE = EncryptionMode.SEED_ONLY
|
||||
TOTP_PURPOSE = 39
|
||||
|
||||
|
||||
def derive_key_from_password(password: str, iterations: int = 100_000) -> bytes:
|
||||
def derive_key_from_password(
|
||||
password: str, salt: bytes = b"", iterations: int = 100_000
|
||||
) -> bytes:
|
||||
"""
|
||||
Derives a Fernet-compatible encryption key from the provided password using PBKDF2-HMAC-SHA256.
|
||||
|
||||
@@ -55,6 +57,7 @@ def derive_key_from_password(password: str, iterations: int = 100_000) -> bytes:
|
||||
|
||||
Parameters:
|
||||
password (str): The user's password.
|
||||
salt (bytes, optional): A salt for key derivation. Defaults to b"" (empty).
|
||||
iterations (int, optional): Number of iterations for the PBKDF2 algorithm. Defaults to 100,000.
|
||||
|
||||
Returns:
|
||||
@@ -80,7 +83,7 @@ def derive_key_from_password(password: str, iterations: int = 100_000) -> bytes:
|
||||
key = hashlib.pbkdf2_hmac(
|
||||
hash_name="sha256",
|
||||
password=password_bytes,
|
||||
salt=b"", # No salt for deterministic key derivation
|
||||
salt=salt, # Use provided salt (default empty for backward compatibility)
|
||||
iterations=iterations,
|
||||
dklen=32, # 256-bit key for Fernet
|
||||
)
|
||||
@@ -99,6 +102,7 @@ def derive_key_from_password(password: str, iterations: int = 100_000) -> bytes:
|
||||
|
||||
def derive_key_from_password_argon2(
|
||||
password: str,
|
||||
salt: bytes = b"\x00" * 16,
|
||||
*,
|
||||
time_cost: int = 2,
|
||||
memory_cost: int = 64 * 1024,
|
||||
@@ -106,8 +110,8 @@ def derive_key_from_password_argon2(
|
||||
) -> bytes:
|
||||
"""Derive an encryption key from a password using Argon2id.
|
||||
|
||||
The defaults follow recommended parameters but omit a salt for deterministic
|
||||
output. Smaller values may be supplied for testing.
|
||||
The defaults follow recommended parameters but use a default salt for deterministic
|
||||
output (backward compatibility). Smaller values may be supplied for testing.
|
||||
"""
|
||||
|
||||
if not password:
|
||||
@@ -120,7 +124,7 @@ def derive_key_from_password_argon2(
|
||||
|
||||
key = hash_secret_raw(
|
||||
secret=normalized,
|
||||
salt=b"\x00" * 16,
|
||||
salt=salt,
|
||||
time_cost=time_cost,
|
||||
memory_cost=memory_cost,
|
||||
parallelism=parallelism,
|
||||
|
||||
Reference in new issue
Block a user