-
Notifications
You must be signed in to change notification settings - Fork 0
KDBX v2 File Format
Stoom edited this page Jan 10, 2017
·
1 revision
+-------------------------------------------------------------------+
| 4 | 4 | 4 |1| 2 | ... | x{3} | 32 | ... |
+--+-----+-----+---+--+----+-----+---------+---------+--------------+
| | | | | | | | |
| | | | | | | | +-> Xml document (could be encrypted)
| | | | | | | +-> Stream start bytes (must match header correlating header)
| | | | | | +-> Repeat of header fields until EOH type
| | | | | +->Header Field Data
| | | | +-> Header Field Size
| | | +-> Header Field Type
| | +-> File Ver
| +-> Sig 2
+-> Sig 1
| kdb | kdbx pre-rel | kdbx relese |
byte 1 | 0x9aa2d903 | 0x9aa2d903 | 0x9aa2d903 |
byte 2 | 0xb54bfb65 | 0xb54bfb66 | 0xb54bfb67 |
- Looks to be keepass version split (major version upper 2 bytes, minor version lower 2 bytes)
- Mask is 0xffff0000 to split major and minor version
- Comment says only lower bytes are important and saved file version cannot be greater than fixed value in release (0x00030001)
- Max version so far is 3.01 (from lib/ser/kdbsfile.cs:80)
Entire header is hashed with SHA-256.
UUID custom class that bases new identifiers off of the Guid class
0: No compression
1: Gzip compression
Not really a flag...
Number of rounds to transform key.
Random data.
0x13101310
A memory stream is used to build the byte array to create a SHA-256 hash.
+----------+----------+
| 32 | 32 |
+-----+----+-----+----+
| |
| +-> GenerateKey32 (Transform Seed by Rounds) (Kdbx.Read.cs:332)
+-> Master Seed
The hashed is stored in an variable named aseKey and is feed into KeePass's ICipherEngine along with the IV to decrypt the stream.
<?xml version="1.0" encoding="utf-16" standalone="yes"?>
<KeePassFile>
<Meta>
<Generator>string</Generator>
<HeaderHash>base64=</HeaderHash>
<DatabaseName />
<DatabaseNameChanged>yyyy-mm-ddThh:mm:ssZ</DatabaseNameChanged>
<DatabaseDescription />
<DatabaseDescriptionChanged>yyyy-mm-ddThh:mm:ssZ</DatabaseDescriptionChanged>
<DefaultUserName />
<DefaultUserNameChanged>yyyy-mm-ddThh:mm:ssZ</DefaultUserNameChanged>
<MaintenanceHistoryDays>int</MaintenanceHistoryDays>
<Color />
<MasterKeyChanged>yyyy-mm-ddThh:mm:ssZ</MasterKeyChanged>
<MasterKeyChangeRec>int</MasterKeyChangeRec>
<MasterKeyChangeForce>int</MasterKeyChangeForce>
<MemoryProtection>
<ProtectTitle>bool</ProtectTitle>
<ProtectUserName>bool</ProtectUserName>
<ProtectPassword>bool</ProtectPassword>
<ProtectURL>bool</ProtectURL>
<ProtectNotes>bool</ProtectNotes>
</MemoryProtection>
<RecycleBinEnabled>bool</RecycleBinEnabled>
<RecycleBinUUID>base64==</RecycleBinUUID>
<RecycleBinChanged>yyyy-mm-ddThh:mm:ssZ</RecycleBinChanged>
<EntryTemplatesGroup>base64==</EntryTemplatesGroup>
<EntryTemplatesGroupChanged>yyyy-mm-ddThh:mm:ssZ</EntryTemplatesGroupChanged>
<HistoryMaxItems>int</HistoryMaxItems>
<HistoryMaxSize>int</HistoryMaxSize>
<LastSelectedGroup>base64==</LastSelectedGroup>
<LastTopVisibleGroup>base64==</LastTopVisibleGroup>
<Binaries />
<CustomData />
</Meta>
<Root>
<Group>
<UUID>base64==</UUID>
<Name>string</Name>
<Notes />
<IconID>int</IconID>
<Times>
<CreationTime>yyyy-mm-ddThh:mm:ssZ</CreationTime>
<LastModificationTime>yyyy-mm-ddThh:mm:ssZ</LastModificationTime>
<LastAccessTime>yyyy-mm-ddThh:mm:ssZ</LastAccessTime>
<ExpiryTime>yyyy-mm-ddThh:mm:ssZ</ExpiryTime>
<Expires>bool</Expires>
<UsageCount>int</UsageCount>
<LocationChanged>yyyy-mm-ddThh:mm:ssZ</LocationChanged>
</Times>
<IsExpanded>bool</IsExpanded>
<DefaultAutoTypeSequence />
<EnableAutoType>null</EnableAutoType>
<EnableSearching>null</EnableSearching>
<LastTopVisibleEntry>base64==</LastTopVisibleEntry>
<Entry>
<UUID>base64==</UUID>
<IconID>int</IconID>
<ForegroundColor />
<BackgroundColor />
<OverrideURL />
<Tags />
<Times>
<CreationTime>yyyy-mm-ddThh:mm:ssZ</CreationTime>
<LastModificationTime>yyyy-mm-ddThh:mm:ssZ</LastModificationTime>
<LastAccessTime>yyyy-mm-ddThh:mm:ssZ</LastAccessTime>
<ExpiryTime>yyyy-mm-ddThh:mm:ssZ</ExpiryTime>
<Expires>bool</Expires>
<UsageCount>int</UsageCount>
<LocationChanged>yyyy-mm-ddThh:mm:ssZ</LocationChanged>
</Times>
<String>
<Key>Notes</Key>
<Value>string</Value
</String>
<String>
<Key>Password</Key>
<Value Protected="True">base64=</Value>
</String>
<String>
<Key>Title</Key>
<Value>string</Value>
</String>
<String>
<Key>URL</Key>
<Value>string</Value>
</String>
<String>
<Key>UserName</Key>
<Value>string</Value>
</String>
<AutoType>
<Enabled>bool</Enabled>
<DataTransferObfuscation>int</DataTransferObfuscation>
</AutoType>
<History />
</Entry>
<Entry>
........
</Entry>
<Group>
<UUID>base64==</UUID>
<Name>string</Name>
<Notes />
<IconID>int</IconID>
<Times>
<CreationTime>yyyy-mm-ddThh:mm:ssZ</CreationTime>
<LastModificationTime>yyyy-mm-ddThh:mm:ssZ</LastModificationTime>
<LastAccessTime>yyyy-mm-ddThh:mm:ssZ</LastAccessTime>
<ExpiryTime>yyyy-mm-ddThh:mm:ssZ</ExpiryTime>
<Expires>bool</Expires>
<UsageCount>int</UsageCount>
<LocationChanged>yyyy-mm-ddThh:mm:ssZ</LocationChanged>
</Times>
<IsExpanded>bool</IsExpanded>
<DefaultAutoTypeSequence />
<EnableAutoType>null</EnableAutoType>
<EnableSearching>null</EnableSearching>
<LastTopVisibleEntry>base64==</LastTopVisibleEntry>
<Entry>
.......
</Entry>
</Group>
<Group>
.....
</Group>
<DeletedObjects>
<DeletedObject>
<UUID>base64==</UUID>
<DeletionTime>yyyy-mm-ddThh:mm:ssZ</DeletionTime>
</DeletedObject>
<DeletedObject>
.....
</DeletedObject>
</DeletedObjects>
</Root>
</KeePassFile>
####Notes: Look into CryptoRandom class.