kdbxtool.security¶
Security-critical components for kdbxtool.
This module contains all security-sensitive code including: - Secure memory handling (SecureBytes) - Cryptographic operations - Key derivation functions - YubiKey challenge-response support
All code in this module should be audited carefully.
- class kdbxtool.security.SecureBytes(data)[source]¶
Bases:
objectA secure container for sensitive byte data that zeroizes on destruction.
Unlike Python’s immutable bytes, SecureBytes uses a mutable bytearray that can be explicitly zeroed when no longer needed. This prevents sensitive data like passwords and cryptographic keys from lingering in memory.
- Usage:
# Basic usage key = SecureBytes(derived_key_bytes) # … use key.data for crypto operations … key.zeroize() # Explicit cleanup
# Context manager (recommended) with SecureBytes(password.encode()) as pwd:
hash = sha256(pwd.data)
# Automatically zeroized here
Note
While this provides defense-in-depth against memory disclosure attacks, Python’s memory management means copies may still exist. For maximum security, consider using specialized libraries like PyNaCl’s SecretBox.
- property data: bytes¶
Access the underlying data as immutable bytes.
- Returns:
The protected data as bytes.
- Raises:
ValueError – If the buffer has already been zeroized.
- class kdbxtool.security.Cipher(*values)[source]¶
Bases:
EnumSupported ciphers for KDBX encryption.
KDBX supports three ciphers: - AES-256-CBC: Traditional cipher, widely supported - ChaCha20: Modern stream cipher, faster in software - Twofish-256-CBC: Legacy cipher, requires oxifish package
Note: KDBX uses plain ChaCha20, not ChaCha20-Poly1305. Authentication is provided by the HMAC block stream.
The UUID values are defined in the KDBX specification.
- classmethod from_uuid(uuid_bytes)[source]¶
Look up cipher by its KDBX UUID.
- Parameters:
uuid_bytes (bytes) – 16-byte cipher identifier from KDBX header
- Returns:
The corresponding Cipher enum value
- Raises:
ValueError – If the UUID doesn’t match any known cipher
- Return type:
- AES256_CBC = b'1\xc1\xf2\xe6\xbfqCP\xbeX\x05!j\xfcZ\xff'¶
- CHACHA20 = b'\xd6\x03\x8a+\x8boL\xb5\xa5$3\x9a1\xdb\xb5\x9a'¶
- TWOFISH256_CBC = b'\xadh\xf2\x9fWoK\xb9\xa3j\xd4z\xf9e4l'¶
- class kdbxtool.security.CipherContext(cipher, key, iv)[source]¶
Bases:
objectContext for encrypting or decrypting data with a KDBX cipher.
This class wraps PyCryptodome cipher implementations with a consistent interface for KDBX operations.
- __init__(cipher, key, iv)[source]¶
Initialize cipher context.
- Parameters:
- Raises:
ValueError – If key or IV size is incorrect
TwofishNotAvailableError – If Twofish requested but oxifish not installed
- Return type:
None
- decrypt(ciphertext)[source]¶
Decrypt ciphertext data.
For AES-CBC and Twofish-CBC, returns decrypted data (caller must remove padding). For ChaCha20, returns stream-decrypted plaintext.
- kdbxtool.security.compute_hmac_sha256(key, data)[source]¶
Compute HMAC-SHA256 of data using the given key.
- kdbxtool.security.constant_time_compare(a, b)[source]¶
Compare two byte sequences in constant time.
This prevents timing attacks where an attacker could measure response time differences to deduce secret values.
- kdbxtool.security.secure_random_bytes(n)[source]¶
Generate cryptographically secure random bytes.
Uses os.urandom which is suitable for cryptographic use.
- kdbxtool.security.verify_hmac_sha256(key, data, expected_mac)[source]¶
Verify HMAC-SHA256 in constant time.
- class kdbxtool.security.AesKdfConfig(rounds, salt)[source]¶
Bases:
objectConfiguration for AES-KDF key derivation.
AES-KDF is supported in both KDBX3 and KDBX4. While Argon2 is generally recommended for new databases, AES-KDF may be preferred for compatibility with older KeePass clients or on systems where Argon2 is slow.
- classmethod fast(salt=None)[source]¶
Create configuration for fast operations (testing only).
WARNING: Uses only 60,000 rounds which provides minimal security. Only use for testing or development.
- Parameters:
salt (bytes | None) – Optional salt (32 random bytes generated if not provided)
- Returns:
AesKdfConfig with minimal parameters
- Return type:
- classmethod high_security(salt=None)[source]¶
Create configuration for high-security applications.
Uses 6,000,000 rounds for stronger protection at the cost of longer unlock times.
- Parameters:
salt (bytes | None) – Optional salt (32 random bytes generated if not provided)
- Returns:
AesKdfConfig with high security parameters
- Return type:
- classmethod standard(salt=None)[source]¶
Create configuration with balanced security/performance.
Uses 600,000 rounds which provides reasonable security while keeping unlock times acceptable on most hardware.
- Parameters:
salt (bytes | None) – Optional salt (32 random bytes generated if not provided)
- Returns:
AesKdfConfig with standard parameters
- Return type:
- class kdbxtool.security.Argon2Config(memory_kib, iterations, parallelism, salt, variant=KdfType.ARGON2D)[source]¶
Bases:
objectConfiguration for Argon2 key derivation.
- variant¶
Argon2 variant (Argon2d or Argon2id)
- __init__(memory_kib, iterations, parallelism, salt, variant=KdfType.ARGON2D)¶
- classmethod default(salt=None, variant=KdfType.ARGON2D)[source]¶
Create configuration with secure defaults.
Alias for standard(). Provides balanced security and performance.
- Parameters:
- Returns:
Argon2Config with recommended security parameters
- Return type:
- classmethod fast(salt=None, variant=KdfType.ARGON2D)[source]¶
Create configuration for fast operations (testing only).
WARNING: This provides minimal security and should only be used for testing or development. Not suitable for production databases.
Parameters: 16 MiB memory, 3 iterations, 2 parallelism
- Parameters:
- Returns:
Argon2Config with minimal parameters
- Return type:
- classmethod high_security(salt=None, variant=KdfType.ARGON2D)[source]¶
Create configuration for high-security applications.
Use for sensitive data where longer unlock times are acceptable. Provides stronger protection against brute-force attacks.
Parameters: 256 MiB memory, 10 iterations, 4 parallelism
- Parameters:
- Returns:
Argon2Config with high security parameters
- Return type:
- classmethod standard(salt=None, variant=KdfType.ARGON2D)[source]¶
Create configuration with balanced security/performance.
Suitable for most use cases. Provides good security with reasonable unlock times on modern hardware.
Parameters: 64 MiB memory, 3 iterations, 4 parallelism
- Parameters:
- Returns:
Argon2Config with standard security parameters
- Return type:
- validate_security()[source]¶
Check that parameters meet minimum security requirements.
- Raises:
ValueError – If parameters are below security minimums
- Return type:
None
- class kdbxtool.security.KdfType(*values)[source]¶
Bases:
EnumSupported Key Derivation Functions in KDBX.
The UUID values are defined in the KDBX specification.
- classmethod from_uuid(uuid_bytes)[source]¶
Look up KDF by its KDBX UUID.
- Parameters:
uuid_bytes (bytes) – 16-byte KDF identifier from KDBX header
- Returns:
The corresponding KdfType enum value
- Raises:
ValueError – If the UUID doesn’t match any known KDF
- Return type:
- ARGON2D = b'\xefcm\xdf\x8c)DK\x91\xf7\xa9\xa4\x03\xe3\n\x0c'¶
- ARGON2ID = b'\x9e)\x8b\x19V\xdbGs\xb2=\xfc>\xc6\xf0\xa1\xe6'¶
- AES_KDF = b'\xc9\xd9\xf3\x9ab\x8aD`\xbft\r\x08\xc1\x8aO\xea'¶
- kdbxtool.security.derive_composite_key(password=None, keyfile_data=None, yubikey_response=None)[source]¶
Create composite key from password, keyfile, and/or YubiKey response.
The composite key is SHA-256(password_hash || keyfile_key || challenge_result).
KeePassXC-compatible YubiKey handling: - The YubiKey response (20 bytes HMAC-SHA1) is SHA-256 hashed - This hash is appended to the other key components before final SHA-256 - The challenge used to obtain the response should be the KDF salt
The keyfile_key is processed according to KeePass keyfile format rules.
- Parameters:
- Returns:
32-byte composite key wrapped in SecureBytes
- Raises:
MissingCredentialsError – If no credentials are provided
ValueError – If yubikey_response is provided but wrong size
- Return type:
- kdbxtool.security.derive_key_aes_kdf(password, config)[source]¶
Derive a 32-byte key using legacy AES-KDF.
This performs repeated AES-ECB encryption of the password using the salt as key. Only use for KDBX3 compatibility.
- Parameters:
password (bytes) – 32-byte password hash
config (AesKdfConfig) – AES-KDF configuration
- Returns:
32-byte derived key wrapped in SecureBytes
- Raises:
ValueError – If password is not 32 bytes
- Return type:
- kdbxtool.security.derive_key_argon2(password, config, *, enforce_minimums=True)[source]¶
Derive a 32-byte key using Argon2.
- Parameters:
password (bytes) – Password bytes (usually composite key hash)
config (Argon2Config) – Argon2 configuration parameters
enforce_minimums (bool) – If True, reject weak parameters
- Returns:
32-byte derived key wrapped in SecureBytes
- Raises:
ValueError – If parameters are invalid or below minimums
- Return type:
- class kdbxtool.security.KeyFileVersion(*values)[source]¶
Bases:
StrEnumSupported KeePass keyfile formats.
- XML_V2¶
XML format v2.0 with hex-encoded key and SHA-256 hash verification. This is the recommended format for new keyfiles. Uses .keyx extension.
- XML_V1¶
Legacy XML format v1.0 with base64-encoded key. Supported for compatibility. Uses .key extension.
- RAW_32¶
Raw 32-byte binary key. Simple but no integrity verification.
- HEX_64¶
64-character hex string (32 bytes encoded as hex).
- XML_V2 = 'xml_v2'¶
- XML_V1 = 'xml_v1'¶
- RAW_32 = 'raw_32'¶
- HEX_64 = 'hex_64'¶
- kdbxtool.security.create_keyfile(path, version=KeyFileVersion.XML_V2)[source]¶
Create a new keyfile at the specified path.
Generates a cryptographically secure 32-byte random key and saves it in the specified format.
- Parameters:
version (KeyFileVersion) – Keyfile format to use. Defaults to XML_V2 (recommended).
- Raises:
OSError – If the file cannot be written.
- Return type:
None
Example
# Create XML v2.0 keyfile (recommended) create_keyfile(“vault.keyx”)
# Create raw binary keyfile create_keyfile(“vault.key”, version=KeyFileVersion.RAW_32)
- kdbxtool.security.create_keyfile_bytes(version=KeyFileVersion.XML_V2)[source]¶
Create a new keyfile and return its contents as bytes.
Generates a cryptographically secure 32-byte random key and encodes it in the specified format.
- Parameters:
version (KeyFileVersion) – Keyfile format to use. Defaults to XML_V2 (recommended).
- Returns:
Keyfile contents as bytes, ready to write to a file.
- Return type:
Example
keyfile_data = create_keyfile_bytes(KeyFileVersion.XML_V2) with open(“my.keyx”, “wb”) as f:
f.write(keyfile_data)
- kdbxtool.security.parse_keyfile(keyfile_data)[source]¶
Parse keyfile data and extract the 32-byte key.
KeePass supports several keyfile formats: 1. XML keyfile (v1.0 or v2.0) - key is base64/hex encoded in XML 2. 32-byte raw binary - used directly 3. 64-byte hex string - decoded from hex 4. Any other size - SHA-256 hashed
- Parameters:
keyfile_data (bytes) – Raw keyfile contents.
- Returns:
32-byte key derived from keyfile.
- Raises:
InvalidKeyFileError – If keyfile format is invalid or hash verification fails.
- Return type:
- class kdbxtool.security.YubiKeyConfig(slot=2, serial=None, timeout_seconds=15.0)[source]¶
Bases:
objectConfiguration for YubiKey challenge-response.
- slot¶
YubiKey slot to use (1 or 2). Slot 2 is typically used for challenge-response as slot 1 is often used for OTP.
- Type:
- serial¶
Optional serial number to select a specific YubiKey when multiple devices are connected. If None, uses the first device. Use list_yubikeys() to discover available devices and serials.
- Type:
int | None
- timeout_seconds¶
Timeout for challenge-response operation in seconds. If touch is required, this is the time to wait for the button press.
- Type:
- kdbxtool.security.check_slot_configured(slot=2, serial=None)[source]¶
Check if a YubiKey slot is configured for HMAC-SHA1.
This is a convenience function to verify that a slot is properly configured before attempting to use it.
- Parameters:
- Returns:
True if the slot is configured for HMAC-SHA1, False otherwise.
- Raises:
YubiKeyNotAvailableError – If yubikey-manager is not installed.
YubiKeyNotFoundError – If no YubiKey is connected (or specified serial not found).
- Return type:
- kdbxtool.security.compute_challenge_response(challenge, config=None)[source]¶
Send challenge to YubiKey and return HMAC-SHA1 response.
This function sends the challenge (the database’s KDF salt) to the YubiKey and returns the HMAC-SHA1 response. The response is computed by the YubiKey hardware using a secret that never leaves the device.
- Parameters:
challenge (bytes) – Challenge bytes (32-byte KDF salt from KDBX header). Must be at least 1 byte.
config (YubiKeyConfig | None) – Optional YubiKey configuration. If not provided, uses slot 2 with 15 second timeout.
- Returns:
20-byte HMAC-SHA1 response wrapped in SecureBytes for automatic zeroization when no longer needed.
- Raises:
YubiKeyNotAvailableError – If yubikey-manager is not installed.
YubiKeyNotFoundError – If no YubiKey is connected.
YubiKeySlotError – If the specified slot is not configured for HMAC-SHA1 challenge-response.
YubiKeyTimeoutError – If the operation times out (e.g., touch was required but not received).
YubiKeyError – For other YubiKey communication errors.
- Return type:
- kdbxtool.security.list_yubikeys()[source]¶
List connected YubiKey devices.
- Returns:
serial: Device serial number (if available)
name: Device name/model
- Return type:
List of dictionaries containing device info
- Raises:
YubiKeyNotAvailableError – If yubikey-manager is not installed.
Modules
Cryptographic primitives and utilities for kdbxtool. |
|
Key Derivation Functions for KDBX databases. |
|
KeePass keyfile creation and parsing. |
|
Secure memory handling for sensitive data. |
|
TOTP (Time-based One-Time Password) implementation per RFC 6238. |
|
YubiKey HMAC-SHA1 challenge-response support. |