KeePass Help Center KeePass Home | Downloads | Translations | Plugins | Donate 
Help Center Home | Forums | Awards | Links 







KDBX File Format Specification

Definition of the KDBX 4.1 file format.


General

KDBX is the KeePass 2.x database file format, which is used for storing user data (user names, passwords, URLs, etc.). It features encryption, data authentication (for detecting corruptions/manipulations), compression, attachment deduplication and extensibility (plugins and ports can store custom data).

This specification defines the latest version (4.1) of the KDBX file format.

Some general notes on the KDBX file format and this specification:

  • Integers are stored in little-endian byte order, i.e. the least significant byte is stored first. For example, the integer 0x12345678 is stored as the byte sequence (0x78, 0x56, 0x34, 0x12).
  • A boolean is stored as one byte. False = 0x00, true = 0x01.
  • Strings are stored in UTF-8 encoding, without a byte-order mark (BOM) and without a null terminator (the length is clear from the context).
  • A UUID is a unique identifier consisting of 16 bytes (128 bits). In this specification, we list the bytes of a UUID in hexadecimal form, without a prefix. For example, 31C1F2E6BF714350BE5805216AFC5AFF = (0x31, 0xC1, 0xF2, 0xE6, 0xBF, 0x71, 0x43, 0x50, 0xBE, 0x58, 0x05, 0x21, 0x6A, 0xFC, 0x5A, 0xFF). In the XML document, UUIDs are stored in Base64 encoding.
  • In this specification, we use the symbol '‖' for the concatenation of two byte sequences, with implicit conversion of the arguments to byte sequences, without padding. Example:
    (0xAB, 0xCD, 0xEF) ‖ 0x12345678 ‖ "Abc" = (0xAB, 0xCD, 0xEF, 0x78, 0x56, 0x34, 0x12, 0x41, 0x62, 0x63).
  • Items marked with a '⟳' symbol should be regenerated each time the KDBX file is saved.
  • The abbreviation 'KDB' stands for 'KeePass Database'. The 'X' indicates that XML is used.

Overall Structure

Overview of a KDBX file:

  1. Header.
  2. SHA-256 hash of the header.
  3. HMAC-SHA-256 hash of the header.
  4. In HMAC-protected block stream:

The SHA-256 hash of the header can be used for checking the integrity of the header, without knowing the master key. It allows detecting unintentional corruptions.

The HMAC-SHA-256 hash of the header can be used for checking the integrity and the authenticity of the header. The correct master key is required for verifying the HMAC. See the section 'Computation of Keys' for details about the computation of the HMAC key.

The input data for the HMAC-protected block stream is encrypted, i.e. we have an Encrypt-then-MAC scheme.


Header

A KDBX file starts as follows:

NameTypeDescription
Signature (1) UInt32 Must be 0x9AA2D903.
Signature (2) UInt32 Must be 0xB54BFB67.
Format version UInt32 The high word is the major version, and the low word is the minor version.
  • An application can load the file if it supports the major version.
  • If the minor version of the file is greater than the one that the application supports, the application may try to load the file, ignoring any unknown items. Certain data may be lost in this case, thus showing a confirmation/warning is recommended.
For KDBX 4.1, the format version value is 0x00040001.
Fields ID-value pairs One or more header fields. See below.

A header field consists of an ID t (byte) and a value V (type depends on t). Let s be the size of V in bytes, as Int32. Each header field is stored as follows:
tsV.

The following header fields are supported:

NameIDTypeDescription
End of header 0 Byte[4] Indicates the end of the header. Must be present exactly once, as the last header field. The value should be the byte array (0x0D, 0x0A, 0x0D, 0x0A).
Encryption algorithm 2 UUID The following encryption algorithms are supported by KeePass (built-in, without a plugin):
  • 31C1F2E6BF714350BE5805216AFC5AFF: AES-256 (NIST FIPS 197, CBC mode, PKCS #7 padding).
  • D6038A2B8B6F4CB5A524339A31DBB59A: ChaCha20 (RFC 8439).
Plugins can provide more encryption algorithms.
Compression algorithm 3 UInt32 0 = no compression, 1 = GZip.
Master salt/seed (⟳) 4 Byte[32] Salt/seed for computing the keys.
Encryption IV/nonce (⟳) 7 Byte[] Initialization vector or nonce for the encryption algorithm. 16 bytes for AES-256, 12 bytes for ChaCha20.
KDF parameters 11 Variant dictionary Parameters for the key derivation function (KDF). See below.
Public custom data 12 Variant dictionary Custom data of plugins/ports. The name of an item should be unique, e.g. "PluginName_ItemName". In this header field, only data that must be readable without decryption should be stored (e.g. data by a key provider plugin required for decryption). All other custom data should be stored in the encrypted XML document (elements //Meta/CustomData, //Group/CustomData and //Entry/CustomData).

The IDs 1, 5, 6, 8, 9 and 10 were used in previous versions of the KDBX file format.

Key derivation function (KDF) parameters. The KDF parameters are stored in a variant dictionary. The following parameters are supported:

NameTypeDescription
All KDFs:
$UUID UUID UUID of the KDF. The following KDFs are supported by KeePass (built-in, without a plugin):
  • C9D9F39A628A4460BF740D08C18A4FEA: AES-KDF.
  • EF636DDF8C29444B91F7A9A403E30A0C: Argon2d.
  • 9E298B1956DB4773B23DFC3EC6F0A1E6: Argon2id.
Plugins can provide more KDFs.
AES-KDF:
S (⟳) Byte[32] Salt/seed.
R UInt64 Rounds.
Argon2:
V UInt32 Version. 0x10 (version 1.0) or 0x13 (version 1.3), as defined in the Argon2 specification. 0x13 is recommended.
S (⟳) Byte[] Salt. Size: minimum 8, maximum 0x3FFFFFFF, recommended 32.
I UInt64 Iterations. Minimum 1, maximum 0xFFFFFFFF.
M UInt64 Memory, in bytes. Minimum 8192, maximum 0x7FFFFFFF.
P UInt32 Parallelism. Minimum 1, maximum 0x00FFFFFF.


Variant Dictionary

A variant dictionary is a name-value dictionary, where the name is a string and the type of the value depends on the item. It is stored as follows:

  1. Format version, as UInt16.
    • The high byte is the major version. It is critical, i.e. an application must refuse to load the file if the major version is unsupported.
    • The low byte is the minor version. It can be ignored, but when encountering an unsupported value type, a confirmation/warning should be displayed or loading should fail.
    The current version is 1.0, i.e. 0x0100.
  2. Zero or more items (see below).
  3. Null terminator byte.

An item looks as follows:

NameTypeDescription
Value type t Byte Supported value types are:
  • 0x04: UInt32.
  • 0x05: UInt64.
  • 0x08: Boolean.
  • 0x0C: Int32.
  • 0x0D: Int64.
  • 0x18: String.
  • 0x42: Byte[].
Name size r Int32 Size of U in bytes.
Name U String (r bytes) Name of the item.
Value size s Int32 Size of V in bytes.
Value V t (s bytes) Value of the item.

The order of the items is arbitrary.


Computation of Keys

For some of the cryptographic primitives used in the KDBX file format, a key is required. The keys are computed as follows:

  1. Let R be the SHA-256 hash of the concatenation of the components of the master key that the user has provided (each optional, in the following order):
    1. SHA-256 hash of the master password (encoded using UTF-8).
    2. Key stored in a key file.
    3. Key provided by a key provider plugin.
    4. Key protected using the Windows user account (DPAPI).
  2. Let T be the result of transforming R using a key derivation function. The function and parameters for it are stored in the header.

With T and the master salt/seed S (stored in the header), the final keys can be computed:

  • If the encryption algorithm needs a 256-bit key (such as AES-256 and ChaCha20), the key is:
    SHA-256(ST).
    If the encryption algorithm needs a key smaller than 256 bits, the key consists of the first bytes of SHA-256(ST).
  • The key for the HMAC-SHA-256 hash of the header is:
    SHA-512(0xFFFFFFFFFFFFFFFF ‖ SHA-512(ST ‖ 0x01)).
  • The key for the HMAC-SHA-256 hash of the i-th block (zero-based index, type UInt64) of the HMAC-protected block stream is:
    SHA-512(i ‖ SHA-512(ST ‖ 0x01)).

The inner encryption key is stored in the inner header and does not depend on the master key. For details, see the description of the inner encryption.


HMAC-Protected Block Stream

When loading the content of a KDBX file, KeePass first verifies the integrity and the authenticity of the data before decrypting, decompressing and parsing it. For this, HMACs are used. Computing only one HMAC for the whole data would be problematic when the data is large. KeePass would either need to read the whole data into the process memory (i.e. a lot of process memory would be required) or read the whole data twice (which would be a problem when I/O is slow, e.g. when loading the KDBX file over a slow network/Internet connection, and temporary files should of course be avoided for multiple reasons). Solution: splitting the data into blocks and protecting each block using a HMAC.

When saving a KDBX file, KeePass splits the input data for this stream into blocks. Let M be the i-th input block (zero-based index, type UInt64) and let s be the size of M (in bytes, as Int32), then an output block (to be stored in the file) looks as follows:
HMAC-SHA-256(isM) ‖ sM.

For computing the HMAC-SHA-256 hash, a key is required. See the section 'Computation of Keys' for details about the computation of the key.

A very small block size results in a large KDBX file (due to the additional HMACs and size values). A very large block size requires a lot of process memory. So, except in special cases (e.g. a small block at the end of the file), neither the minimum nor the maximum is a good choice for the block size; a good size is in the "middle". When saving a KDBX file, KeePass currently uses 1048576 (i.e. 1 MB) as size for every input block except the last one (which may be smaller).

The HMAC-protected block stream is terminated by an output block for an empty input block (i.e. M empty, s = 0).


Inner Header

The inner header (which is called "inner" because it is compressed and encrypted) consists of one or more header fields. A header field consists of an ID t (byte) and a value V (type depends on t). Let s be the size of V in bytes, as Int32. Each header field is stored as follows:
tsV.

The following header fields are supported:

NameIDTypeDescription
End of header 0 Indicates the end of the header. Must be present exactly once, as the last header field. The value should be empty.
Inner encryption algorithm 1 Int32 2 = Salsa20, 3 = ChaCha20 (default, recommended). See 'Inner Encryption'.
Inner encryption key (⟳) 2 Byte[] See 'Inner Encryption'.
Binary content 3 Byte[] The value is fC, where f is a flags byte and C is the content of a binary (attachment). The flag 0x01 indicates that the binary content should be protected in the process memory. A binary content is referenced in the XML document by its index in the inner header (the first binary content has index 0, the second one has index 1, etc.).


Inner Encryption

Most XML parsers work with regular strings, which may be difficult to erase from the process memory. So, if sensitive data would be stored unencryptedly in the XML document, a process memory protection could not be realized properly. Solution: all data that should be protected in the process memory is stored in encrypted form in the XML document. For this, the encryption algorithm and key stored in the inner header are used. The encryption algorithm is a stream cipher and its state is not reset for each data to be protected (thus the order in which the data to be protected appears is important). For example, if there is an entry A with a password consisting of 23 UTF-8 bytes and an entry B with a password consisting of 19 UTF-8 bytes (and A appears before B), then the password of A is encrypted using the first 23 output bytes of the stream cipher and the password of B is encrypted using the next (not first) 19 output bytes of the stream cipher. When loading a KDBX file, an application typically decrypts the protected data and immediately protects it using a method suitable for the current operating system (e.g. DPAPI on Windows).

We emphasize that the only purpose of the inner encryption is to support the process memory protection. The inner encryption has no effect on the cryptographic security of the KDBX file format.

Let K be the inner encryption key stored in the inner header. The parameters for the inner encryption algorithm are derived as follows:

  • Salsa20. K should consist of 32 bytes. The key for Salsa20 is SHA-256(K), and the nonce is (0xE8, 0x30, 0x09, 0x4B, 0x97, 0x20, 0x5D, 0x2A).
  • ChaCha20. K should consist of 64 bytes. Compute H := SHA-512(K). The key for ChaCha20 is (H[0], ..., H[31]), and the nonce is (H[32], ..., H[43]).

XML Document

The KDBX XML document contains most of the user data.

The format of the KDBX XML document is specified by the following XML schema (including annotations):
KDBX_XML.xsd (KDBX 4.1 XML Schema).









Get KeePass