kdbxtool.parsing

KDBX binary format parsing and building.

This module handles low-level binary format operations: - Header parsing and validation - KDBX4 payload encryption/decryption - XML payload handling

All parsing uses context classes for structured binary operations.

class kdbxtool.parsing.BuildContext(_parts=<factory>)[source]

Bases: object

Stateful writer for building binary data.

Accumulates bytes in a list and joins them efficiently at the end.

Example

ctx = BuildContext() ctx.write(MAGIC_BYTES) ctx.write_u32(version) ctx.write_tlv(FIELD_TYPE, field_data) result = ctx.build()

Parameters:

_parts (list[bytes])

__init__(_parts=<factory>)
Parameters:

_parts (list[bytes])

Return type:

None

build()[source]

Join all accumulated bytes and return result.

Return type:

bytes

property size: int

Total size of accumulated bytes.

write(data)[source]

Write raw bytes.

Parameters:

data (bytes)

Return type:

None

write_bytes_prefixed(data)[source]

Write length-prefixed bytes (4-byte little-endian length prefix).

Parameters:

data (bytes)

Return type:

None

write_tlv(type_id, data, type_size=1)[source]

Write Type-Length-Value field.

Parameters:
  • type_id (int) – Field type identifier

  • data (bytes) – Field data

  • type_size (int) – Size of type field in bytes (1 for KDBX4, can vary)

Return type:

None

write_u16(value)[source]

Write unsigned 16-bit little-endian integer.

Parameters:

value (int)

Return type:

None

write_u32(value)[source]

Write unsigned 32-bit little-endian integer.

Parameters:

value (int)

Return type:

None

write_u64(value)[source]

Write unsigned 64-bit little-endian integer.

Parameters:

value (int)

Return type:

None

write_u8(value)[source]

Write unsigned 8-bit integer.

Parameters:

value (int)

Return type:

None

class kdbxtool.parsing.ParseContext(data, offset=0, _path=<factory>)[source]

Bases: object

Stateful reader for binary data with error context tracking.

Tracks the current offset and a path of nested scopes for error messages. When parsing fails, error messages include the full path to the failure point.

Example

ctx = ParseContext(data) with ctx.scope(“header”):

magic = ctx.read(8, “magic”) with ctx.scope(“version”):

major = ctx.read_u16(“major”)

# Error would show: “Unexpected EOF at header/version/major, offset 10”

Parameters:
__init__(data, offset=0, _path=<factory>)
Parameters:
Return type:

None

property exhausted: bool

True if all bytes have been read.

offset: int = 0
peek(n)[source]

Peek at next n bytes without advancing offset.

Parameters:

n (int) – Number of bytes to peek

Returns:

The bytes (may be shorter if near end of data)

Return type:

bytes

property position: int

Current read position (alias for offset).

read(n, name='')[source]

Read n bytes from current position.

Parameters:
  • n (int) – Number of bytes to read

  • name (str) – Optional name for error messages

Returns:

The bytes read

Raises:

CorruptedDataError – If not enough bytes available

Return type:

bytes

read_bytes_prefixed(name='')[source]

Read length-prefixed bytes (4-byte little-endian length prefix).

Parameters:

name (str) – Optional name for error messages

Returns:

The bytes read (not including the length prefix)

Return type:

bytes

read_u16(name='')[source]

Read unsigned 16-bit little-endian integer.

Parameters:

name (str)

Return type:

int

read_u32(name='')[source]

Read unsigned 32-bit little-endian integer.

Parameters:

name (str)

Return type:

int

read_u64(name='')[source]

Read unsigned 64-bit little-endian integer.

Parameters:

name (str)

Return type:

int

read_u8(name='')[source]

Read unsigned 8-bit integer.

Parameters:

name (str)

Return type:

int

property remaining: int

Number of bytes remaining to read.

scope(name)[source]

Create a named scope for error context.

Parameters:

name (str) – Scope name to add to error path

Return type:

Iterator[None]

Example

with ctx.scope(“inner_header”):

field_type = ctx.read_u8(“type”)

skip(n, name='')[source]

Skip n bytes.

Parameters:
  • n (int) – Number of bytes to skip

  • name (str) – Optional name for error messages

Raises:

CorruptedDataError – If not enough bytes available

Return type:

None

data: bytes
class kdbxtool.parsing.CompressionType(*values)[source]

Bases: IntEnum

Compression algorithms for KDBX payload.

NONE = 0
GZIP = 1
class kdbxtool.parsing.HeaderFieldType(*values)[source]

Bases: IntEnum

Outer header field types for KDBX format.

These are the TLV (Type-Length-Value) field identifiers in the outer (unencrypted) header.

END = 0
COMMENT = 1
CIPHER_ID = 2
COMPRESSION_FLAGS = 3
MASTER_SEED = 4
TRANSFORM_SEED = 5
TRANSFORM_ROUNDS = 6
ENCRYPTION_IV = 7
PROTECTED_STREAM_KEY = 8
STREAM_START_BYTES = 9
INNER_RANDOM_STREAM_ID = 10
KDF_PARAMETERS = 11
PUBLIC_CUSTOM_DATA = 12
class kdbxtool.parsing.InnerHeaderFieldType(*values)[source]

Bases: IntEnum

Inner header field types for KDBX4 format.

These appear after decryption, before the XML payload.

END = 0
INNER_RANDOM_STREAM_ID = 1
INNER_RANDOM_STREAM_KEY = 2
BINARY = 3
class kdbxtool.parsing.KdbxHeader(version, cipher, compression, master_seed, encryption_iv, kdf_type, kdf_salt, argon2_memory_kib=None, argon2_iterations=None, argon2_parallelism=None, aes_kdf_rounds=None, inner_random_stream_id=None, inner_random_stream_key=None, stream_start_bytes=None, protected_stream_key=None, raw_header=b'')[source]

Bases: object

Parsed KDBX header data.

This class holds all fields from the outer header in a typed format. It supports both KDBX3 and KDBX4, with version-specific fields optional.

Parameters:
version: KdbxVersion
cipher: Cipher
compression: CompressionType
master_seed: bytes
encryption_iv: bytes
kdf_type: KdfType
kdf_salt: bytes
argon2_memory_kib: int | None
argon2_iterations: int | None
argon2_parallelism: int | None
aes_kdf_rounds: int | None
inner_random_stream_id: int | None
inner_random_stream_key: bytes | None
stream_start_bytes: bytes | None
protected_stream_key: bytes | None
raw_header: bytes
__init__(version, cipher, compression, master_seed, encryption_iv, kdf_type, kdf_salt, argon2_memory_kib=None, argon2_iterations=None, argon2_parallelism=None, aes_kdf_rounds=None, inner_random_stream_id=None, inner_random_stream_key=None, stream_start_bytes=None, protected_stream_key=None, raw_header=b'')
Parameters:
Return type:

None

classmethod parse(data)[source]

Parse KDBX header from raw bytes.

Parameters:

data (bytes) – Raw file data starting from beginning

Returns:

Tuple of (parsed header, number of bytes consumed)

Raises:
Return type:

tuple[Self, int]

to_bytes()[source]

Serialize header to KDBX4 binary format.

Returns:

Binary header data ready to be written to file

Raises:
Return type:

bytes

class kdbxtool.parsing.KdbxVersion(*values)[source]

Bases: IntEnum

KDBX file format versions.

KDBX3 = 3
KDBX4 = 4
class kdbxtool.parsing.Kdbx3Reader(data)[source]

Bases: object

Reader for KDBX3 format databases.

KDBX3 uses AES-KDF for key derivation and content hashed blocks for payload integrity verification.

Parameters:

data (bytes)

__init__(data)[source]

Initialize reader with KDBX3 file data.

Parameters:

data (bytes) – Complete KDBX3 file contents

Return type:

None

decrypt(password=None, keyfile_data=None, transformed_key=None)[source]

Decrypt the KDBX3 file.

Parameters:
  • password (str | None) – Optional password

  • keyfile_data (bytes | None) – Optional keyfile contents

  • transformed_key (bytes | None) – Optional pre-computed transformed key (skips KDF)

Returns:

DecryptedPayload with header, synthetic inner header, and XML

Raises:
Return type:

DecryptedPayload

kdbxtool.parsing.read_kdbx3(data, password=None, keyfile_data=None, transformed_key=None)[source]

Read and decrypt a KDBX3 database.

Parameters:
  • data (bytes) – Complete KDBX3 file contents

  • password (str | None) – Optional password

  • keyfile_data (bytes | None) – Optional keyfile contents

  • transformed_key (bytes | None) – Optional pre-computed transformed key (skips KDF)

Returns:

DecryptedPayload containing header, inner header, and XML data

Raises:
Return type:

DecryptedPayload

class kdbxtool.parsing.DecryptedPayload(header, inner_header, xml_data, transformed_key=None)[source]

Bases: object

Result of decrypting a KDBX4 file.

Contains all data needed to work with the database.

Parameters:
header: KdbxHeader
inner_header: InnerHeader
xml_data: bytes
transformed_key: bytes | None
__init__(header, inner_header, xml_data, transformed_key=None)
Parameters:
Return type:

None

class kdbxtool.parsing.InnerHeader(random_stream_id, random_stream_key, binaries)[source]

Bases: object

KDBX4 inner header data.

The inner header appears after decryption, before the XML payload. It contains the protected stream cipher settings and binary attachments.

Parameters:
random_stream_id: int
random_stream_key: bytes
binaries: dict[int, tuple[bool, bytes]]
__init__(random_stream_id, random_stream_key, binaries)
Parameters:
Return type:

None

class kdbxtool.parsing.Kdbx4Reader(data)[source]

Bases: object

Reader for KDBX4 database files.

Parameters:

data (bytes)

__init__(data)[source]

Initialize reader with file data.

Parameters:

data (bytes) – Complete KDBX4 file contents

Return type:

None

decrypt(password=None, keyfile_data=None, transformed_key=None, yubikey_response=None)[source]

Decrypt the KDBX4 file.

Parameters:
  • password (str | None) – Optional password

  • keyfile_data (bytes | None) – Optional keyfile contents

  • transformed_key (bytes | None) – Optional precomputed transformed key (skips KDF)

  • yubikey_response (bytes | None) – Optional 20-byte YubiKey HMAC-SHA1 response

Returns:

DecryptedPayload with header, inner header, XML, and transformed_key

Raises:

ValueError – If decryption fails (wrong credentials, corrupted file)

Return type:

DecryptedPayload

class kdbxtool.parsing.Kdbx4Writer[source]

Bases: object

Writer for KDBX4 database files.

BLOCK_SIZE = 1048576
encrypt(header, inner_header, xml_data, password=None, keyfile_data=None, transformed_key=None, yubikey_response=None)[source]

Encrypt database to KDBX4 format.

Parameters:
  • header (KdbxHeader) – Outer header configuration

  • inner_header (InnerHeader) – Inner header with stream cipher and binaries

  • xml_data (bytes) – XML database content

  • password (str | None) – Optional password

  • keyfile_data (bytes | None) – Optional keyfile contents

  • transformed_key (bytes | None) – Optional precomputed transformed key (skips KDF)

  • yubikey_response (bytes | None) – Optional 20-byte YubiKey HMAC-SHA1 response

Returns:

Complete KDBX4 file as bytes

Return type:

bytes

kdbxtool.parsing.read_kdbx4(data, password=None, keyfile_data=None, transformed_key=None, yubikey_response=None)[source]

Convenience function to read a KDBX4 file.

Parameters:
  • data (bytes) – Complete file contents

  • password (str | None) – Optional password

  • keyfile_data (bytes | None) – Optional keyfile contents

  • transformed_key (bytes | None) – Optional precomputed transformed key (skips KDF)

  • yubikey_response (bytes | None) – Optional 20-byte YubiKey HMAC-SHA1 response

Returns:

DecryptedPayload with header, inner header, XML, and transformed_key

Return type:

DecryptedPayload

kdbxtool.parsing.write_kdbx4(header, inner_header, xml_data, password=None, keyfile_data=None, transformed_key=None, yubikey_response=None)[source]

Convenience function to write a KDBX4 file.

Parameters:
  • header (KdbxHeader) – Outer header configuration

  • inner_header (InnerHeader) – Inner header with stream cipher and binaries

  • xml_data (bytes) – XML database content

  • password (str | None) – Optional password

  • keyfile_data (bytes | None) – Optional keyfile contents

  • transformed_key (bytes | None) – Optional precomputed transformed key (skips KDF)

  • yubikey_response (bytes | None) – Optional 20-byte YubiKey HMAC-SHA1 response

Returns:

Complete KDBX4 file as bytes

Return type:

bytes

Modules

context

Parsing and building context classes for binary data.

header

KDBX header parsing and structures.

kdbx3

KDBX3 payload encryption and decryption.

kdbx4

KDBX4 payload encryption and decryption.