How key_derivation and key_verification functions are implemented of a 7-zip archive's encryption mechanism?

Tag: encryption , cryptography , 7zip , password-recovery , cryptanalysis Author: skywyf Date: 2012-09-01

I am curious about how password recovery works for password protected files. And I want to know the exact flow of the 7-zip encryption mechanism.

7-zip uses AES-256 encryption algorithm in CBC mode, to encrypt files or a folder. The key is generated from user supplied pass-phrase based on SHA-256 hash function. The SHA-256 is executed 2^19 (524288) times to increase the cost of exhaustive search. Also, to help reduce the risk of dictionary attacks, salt is appended to original pass-phrase before generating hash.

My First question is how does key_derivation function work to generate a 256-bit key ? What is importance of IV for AES CBC mode and how it is generated?

My second and most important question is how key is verified to decrypt the 7-zip archive ? I mean how does its key_verification function work ?

Best Answer

The key derivation function is in the source of file 7zAes.cpp, it's called:

void CKeyInfo::CalculateDigest()

and it creates the key using a proprietary (rather dull) mechanism.

I haven't been able to find the key_verification method yet, if it exists. I'll let you know if I do find it.


Documentation - including the specifications of the 7zip container format - seems to be missing in action. I even haven't had the pleasure to find a single source code comment in the crypto libs.
I agree with you, I went through the same code to know how key is generated. But two things i didn't get actually. First, since numRounds is calculated using "NumCyclesPower" which is initiated to zero. Then how this "for (UInt64 round = 0; round < numRounds; round++) " loop is supposed to run 2^19 times ?
Second, pass-phrase is appended without any encoding (i.e. UTF-16) mechanism. Does it means 7-zip does not using any encoding mechanism to generate a long string input message for SHA-256?
The inputs for the Sha256_Update is all bytes, Password seems to be a CByteArray, but I cannot directly see where it is set, and with this code base I would not know where to look for that either.