Skip to content

Conversation

@magnumripper
Copy link
Member

Despite comments in code, the existing support appeared to be v1 only. This new clause is tested with a v4 database and keyfile.

Copy link
Member

@solardiz solardiz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know anything about the "newer format", but I made some comments on the code assuming it can end up running on arbitrary/wrong input.

@magnumripper magnumripper force-pushed the keepass-keyfile-v2 branch 2 times, most recently from 67aaeec to 070fc3a Compare December 11, 2025 21:58
@magnumripper
Copy link
Member Author

magnumripper commented Dec 11, 2025

Samples added to john-samples.

The new (well it was many many years ago) format for an XML keyfile is like this:

<?xml version="1.0" encoding="UTF-8"?>
<KeyFile>
    <Meta>
        <Version>2.0</Version>
    </Meta>
    <Key>
        <Data Hash="50BD7B21">
            4C772D15 A5D58BEC 0C707345 ECEBDFE2
            18F0529A 4882FE3C D48F00E5 4B733073
        </Data>
    </Key>
</KeyFile>

The 50BD7B21 is supposedly a CRC32 of the following 32 bytes of key data, not required and not used nor needed in any way for opening (or cracking) a database. If that attribute exists, KeePass would warn if it doesn't match. We don't currently even validate it (I fail to arrive at the CRC above, and I didn't care to figure out why - maybe endianess).

The old format (which we already supported) was more like this (IIRC) for the same 32 byte key:

  <?xml version="1.0" encoding="UTF-8"?>
  <KeyFile>
      <Meta>
          <Version>1.0</Version>
      </Meta>
      <Key>
          <Data>THctFaXVi+wMcHNF7Ovf4hjwUppIgv481I8A5UtzMHM=</Data>
      </Key>
  </KeyFile>

I think there might be whitespace between <Data> and the Base64. We now handle that.

We don't have such sample (the samples we had are "any file used as a key file", not XML). I may try to create one for john-samples later just for completeness.

@magnumripper magnumripper force-pushed the keepass-keyfile-v2 branch 2 times, most recently from 2a7da6e to 49e412d Compare December 11, 2025 22:15
@magnumripper
Copy link
Member Author

Sorry I jumped the gun with requesting a review, I think it's good to go now. Tested with v2 and mockup v1.

@magnumripper
Copy link
Member Author

We don't currently even validate it (I fail to arrive at the CRC above, and I didn't care to figure out why - maybe endianess).

Turns out KeePass 2.x and KeePassXC calculate this CRC differently, making it pretty much useless. I will not add any check, it's just overkill.

Copy link
Member

@solardiz solardiz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a comment on one code issue. Also, maybe remove unsigned from definition of buffer instead of all the casts?

data = p;
p = strstr(p, "</Data>");
printf ("%s", base64_convert_cp(data, e_b64_mime, p - data, b64_decoded, e_b64_hex, sizeof(b64_decoded), flg_Base64_NO_FLAGS, 0));
if (p == NULL || p - buffer < 44) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably be != 44 rather than < 44 here. That would be consistent with the check for hex.

Copy link
Member Author

@magnumripper magnumripper Dec 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually no, because there may be whitespace (of any sort) between the Base64 and </Data>.

Admittedly we don't know they are 44 actual Base64 characters anyway. I'll see if base64_convert_cp returns something useful. BTW I don't recognize that _cp suffix, need to check what the heck that is.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK so I can get an output size from base64_convert... but it returns 64 no matter what garbage I feed it. There are also means for an error variable but it always returns "no error". I'm ignoring this for now.

The existing support was keyfile v1 only (meaning xml keyfile v1 of
KeePass v2).

This adds support for xml keyfile v2, tested with a v4 database.
Also adds some robustness.
@magnumripper magnumripper merged commit 21c19dc into openwall:bleeding-jumbo Dec 12, 2025
33 of 34 checks passed
@magnumripper magnumripper deleted the keepass-keyfile-v2 branch December 12, 2025 00:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants