Score:0

Explanation of KeePass 2 database key calculation?

yt flag

I am currently taking a course in university where we are working with a KeePass 2 database file. I am still very new to everything which has to do with encryption.

First I am going to provide the information which was given to me:

A Keepass 2 database file contains different headers, the important ones are the following:

  • end of header (after this header follows the encrypted database)
  • master seed
  • transform seed
  • transform rounds
  • encryption initialisation vector (IV)
  • stream start bytes (the first 32 bytes of the decrypted database)

After the headers there follows the with AES-256 in CBC-Mode encrypted datastream. The first 32 bytes of the decrypted datastream are randomly chosen bytes and are getting stored in the stream start bytes header. If this headers content matches the decrypted datastream then the password is correct. The Key for the AES-256-CBC encryption is calculated like the following:

$credentials=\text{SHA-256}(\text{SHA-256}(password))$

$transformedCredentials=\text{SHA-256}(\text{AES-256}_{\text{transform_seed}}^{\text{transform_rounds}}(credentials))$

$key=\text{SHA-256}(masterSeed || transformedCredentials)$

The Operator || signifies stream concatenation and $AES-256_K^t(m)$ means that we use AES-256 in ECB Mode with key K t-times on m.

Our task was to write a Java application which cracks the password and I did this but I am still a bit confused about some aspects of the database format and the calculation of the key.

My first thing where I was wondering about, was the usage of the ECB mode for the calculation of the transformed credentials. My teacher told me that ECB is not a good encryption mode and it should never be used for encryption but why is it used here? Isn't it somehow weakening the encryption?

Speaking of weakening the encryption, isn't the storing of the 32 bytes in the stream start bytes header not weakening the encryption as well? Only because of this header I was able to crack to the database. I know that it somehow is necessary to check if a password is correct, but couldn't we hypothecially store the bytes on another way so that I (in this case the intruder) not access it as easy as it is now? Or is there a way to implement the same functionality so that the real users password can still be checked but we don't have to store the plain text data?

On the other hand I would just blackbox the other two things and I think that it is not weakening the encrpytion. Then in my opinion isn't the calculation of the key slightly overkill? Like why are we even calculating the transformed credentials? It's not like it makes the cracking harder or? I mean yes I have to use AES-256 more times in a row but I have the feeling that it doesn't make the brute forcing much harder/longer, or am I wrong here? How I understood it only the length/complexity of the password is deciding about how hard it is to brute force something.

I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.