|
||||
|
On this page, only the enhancements/changes from KDBX 3.1
to KDBX 4 are described. A complete specification of the latest format can be
found here: KDBX File Format Specification.
IntroductionKeePass 2.35 introduces version 4 of the KDBX file format. This new format features both improvements and new capabilities. These are outlined in the following sections. There are a few changes to the inner XML format since KDBX 3.1
(e.g. the Migration Phase. As not all major KeePass ports have finished adding support for KDBX 4 yet, for now KeePass 2.35 saves databases in this new format only when at least one of the following conditions is fulfilled:
Since KeePass 2.44, selecting ChaCha20 as file encryption algorithm also enforces the KDBX 4 format. As soon as all major KeePass ports support KDBX 4, KeePass will always save in this format. Argon2As of KDBX 4, the Argon2 key derivation function can be used for transforming the master key (as protection against dictionary attacks). Argon2 is the winner of the Password Hashing Competition. Up to KDBX 3.1, KeePass used AES-KDF, a key derivation function based on iterating the Advanced Encryption Standard (AES). The main advantage of Argon2 over AES-KDF is that it provides a better resistance against GPU/ASIC attacks (due to being a memory-hard function). Users can now choose between AES-KDF and Argon2 in the database settings dialog (tab 'Security'). For Developers
The Argon2 implementation can be found in Argon2Kdf.Core.cs.
The file Argon2Kdf.cs defines default values for parameters and
implements methods for the key derivation infrastructure.
Only the Argon2d variant of Argon2 is supported
(a strong defense against GPU/ASIC cracking attacks is the most important goal,
and Argon2d here is better than Argon2i;
side-channel timing attacks are basically irrelevant, because
KeePass is a local application, not a remote server).KeePass' Argon2 implementation supports all parameters that are defined in the official specification, but only the number of iterations, the memory size and the degree of parallelism can be configured by the user in the database settings dialog. For the other parameters, KeePass chooses reasonable defaults: a 256-bit salt is generated by a CSPRNG each time a database is saved, the tag length is 256 bits, no secret key or associated data. All versions of Argon2d (1.0 to 1.3) are supported; KeePass uses the latest version 1.3 by default. Extensible Key DerivationPlugins can provide other key derivation functions (for transforming the master key) now. For Developers
Up to KDBX 3.1, the number of rounds for AES-KDF was stored in
the header field with ID 6 (TransformRounds ), and the
seed for the transformation was stored in the header field with
ID 5 (TransformSeed ).
These two fields are obsolete now.As of KDBX 4, key derivation function parameters are stored in the header field with ID 11 ( KdfParameters ).
The parameters are serialized as a VariantDictionary
(with the KDF UUID being stored in '$UUID ');
see the files KdfParameters.cs and VariantDictionary.cs.
For details on the parameters being used by AES-KDF and Argon2,
see AesKdf.cs and Argon2Kdf.cs.A VariantDictionary is a key-value dictionary (with the
key being a string and the value being an object),
which is serialized as follows:
For Developers
Up to KDBX 3.1, header field lengths were 2 bytes wide.
As of KDBX 4, they are 4 bytes wide.
This change makes the implementation of other key derivation
functions possible, whose parameters may require more than
64 KB space.
Furthermore, plugin-provided header data
can be longer than 64 KB.
Improved Header AuthenticationIn KDBX 4, header data is authenticated using HMAC-SHA-256. Up to KDBX 3.1, header data was authenticated using a SHA-256 hash stored in the encrypted part of the database file. The HMAC-SHA-256 approach used in KDBX 4 has various advantages. One advantage is that KeePass can verify the header before trying to decrypt the remaining part, which prevents trying to decrypt incorrect data. For Developers
In KDBX 4, the HeaderHash element in the XML part is
now obsolete and is not stored anymore.
The new header authentication using HMAC-SHA-256 is mandatory.Directly after the header, a (non-encrypted) SHA-256 hash of the header is stored (which allows the detection of unintentional corruptions, without knowing the master key). Directly after the hash, the HMAC-SHA-256 value of the header is stored. Improved Data AuthenticationIn KDBX 4, a data block is authenticated via a HMAC-SHA-256 of the ciphertext (an Encrypt-then-MAC scheme). Up to KDBX 3.1, a data block was authenticated by verifying a SHA-256 hash of the block after decrypting it (like a MAC-then-Encrypt scheme). Although the Encrypt-then-MAC scheme (KDBX 4) in general is considered to be more secure than a MAC-then-Encrypt scheme (KDBX 3.1), we do not believe that KDBX 3.1 files were insecure (because in the specific case of a KDBX file, the authenticated data blocks usually are large and a block cipher in CBC mode is used). Anyway, we believe it is a good idea to switch to the scheme that in general is considered to be the most secure (even if it doesn't actually make any real difference in the KDBX case). Furthermore, Encrypt-then-MAC has practical advantages. For example, one advantage is that KeePass can verify the authenticity of a data block before trying to decrypt it; this avoids block cipher padding exceptions (for KDBX 3.1, KeePass automatically translated these to file corruption exceptions; although this worked, detecting incorrect data before running into such exceptions is cleaner). For Developers
For the stream that loads/saves data blocks authenticated using HMAC-SHA-256,
see the new file HmacBlockStream.cs.
This stream is similar to the HashedBlockStream used
for KDBX 3.1, but uses a HMAC instead of just a hash.
Furthermore, in KDBX 4 the HMAC is computed over the
ciphertext, whereas in KDBX 3.1 plaintext hashes were computed
(and then encrypted together with the plaintext).The ith block produced by HmacBlockStream looks as follows:
After the header and its HMAC, the encrypted data follows, splitted into arbitrarily many blocks of the form above. When KeePass 2.35 writes a KDBX file, it uses n = 220, i.e. the encrypted data is splitted into 1 MB blocks. Extensible HeaderThe header of KDBX 4 files is extensible by plugins. For Developers
Plugin-provided header data is stored in the header field with ID 12.
The value is a serialized VariantDictionary .
For Plugin Developers
Note that the header data is not encrypted and is only present in KDBX
files (not in XML exports). Unless the additional header data
really must be available without decryption, it is
highly recommended that plugins store additional data in
the CustomData dictionary of PwDatabase instead.
CustomData is serialized in the XML part,
i.e. for KDBX files it is encrypted, and it is also present in
XML exports.
ChaCha20Support for the ChaCha20 encryption algorithm (with 256-bit key and 96-bit nonce, as specified in RFC 7539/8439) has been added. ChaCha20 is the successor of the Salsa20 algorithm (which is included in the eSTREAM portfolio). It can be activated as KDBX file encryption algorithm in the database settings dialog. Furthermore, ChaCha20 supersedes Salsa20 as default for generating the inner random stream of KDBX 4 files. For Developers
Up to KDBX 3.1, the encryption IV stored in the KDBX header
(field with ID 7, EncryptionIV )
was always 16 bytes (128 bits) long.
As of KDBX 4, the encryption IV length is retrieved from the
cipher implementation and the KDBX header field stores an
encryption IV of exactly this length.
For ChaCha20, that is 12 bytes (96 bits).
For Plugin Developers
Encryption algorithm plugin developers, please note the following.
The default IV length continues to be 16 bytes (128 bits).
If your cipher engine implements the ICipherEngine2
interface, you can specify a different IV length via the
IVLength property.Via the KeyLength property of ICipherEngine2 ,
you can specify a key length. The default continues to be
32 bytes (256 bits). If you specify a different key length,
KeePass uses a cryptographically secure method to derive a key
of the requested length from the master key.
Extensible Entries and GroupsPlugins can now store custom data in entries and groups. Up to now, plugins for instance have stored custom data in string fields of entries. This worked, but cluttered up the entry string list and wasn't nice from a design point of view. As of KDBX 4, every entry and every group has a key-value dictionary, in which plugins can store their data. For Developers
PwEntry and PwGroup now have a
CustomData property.
This property has the same type as CustomData of
PwDatabase , and is serialized analogously
(same XML structure).
Inner HeaderKDBX 4 files have an inner, binary header. This header precedes the XML part; especially, it is compressed (if the compression option is turned on) and encrypted (which is the reason why we call it the inner header). Directly after the inner header, the XML part follows (in the same compression and encryption stream). The inner header can store entry attachments, which is the primary motivation for the introduction of the inner header. Up to KDBX 3.1, entry attachments were encoded using Base64 and stored in the XML part. Compared to this, the KDBX 4 inner header approach results in a reduced database file size and improved loading/saving performance. For Developers
The structure of the inner header is similar to the one of the outer header.
It consists of arbitrarily many items of the following form:
Page History
|
|
||