2
$\begingroup$

I am analysing a small, bespoke end-to-end encryption service's source code, in particular their user registration process. I am finding some interesting things going on and I am wondering if there's some vulnerabilities here:

  • The client code generates a random Master Key for the user which is 128 bits. This is used to encrypt data on the service.

  • A password based key derivation function is run on the user's Password to produce a Password Derived Key of 128 bits. A salt is not used at all here.

  • The Password Derived Key is used to encrypt the user's Master Key with AES in ECB mode.

  • Some half-random Temporary Data is created of 128 bits. I am not sure what this Temporary Data is used for, I haven't seen it being used for anything in particular anywhere else in the code. Anyway, the first 32 bits are randomly generated, the second 32 bits are zero, the third 32 bits are zero, and the final 32 bits are randomly generated. The array as 32 bit words might look something like: [1502582904, 0, 0, 3153058828].

  • The same Password Derived Key is used to encrypt the Temporary Data with AES in ECB mode as well.

  • The encrypted Master Key and encrypted Temporary Data are concatenated together and sent to the server API to create the account on the server. The API then sends back to the user an email confirmation code that the user uses to confirm their email. The confirmation code is the Base64 encoding of this data concatenated (||) together:

"emailconfirmlink:" || some metadata || encrypted Master Key || encrypted Temporary Data

So the obvious vulnerability seems to be that they send the user's encrypted Master Key back to the user via email for no apparent reason instead of just randomly generating a token on the server side and expecting the user to return that in order to complete the email confirmation. That would allow anyone who can read internet traffic a chance at cracking many user passwords at once pretty easily as there is no salt in the key derivation process to prevent rainbow tables.

I am wondering about another vulnerability in that the Password Derived Key has encrypted the Master Key, but it has also been used to encrypt the Temporary Data as well. So we have:

AES-ECB(Password Derived Key, Master Key)
AES-ECB(Password Derived Key, Temporary Data)

We know AES-ECB is not good at encrypting multiple blocks under the same key. So it has encrypted two blocks now under the same key. Also the Temporary Data has 64 bits of known plaintext in the middle of the second block (all zeros). Also the attacker can see the AES-ECB ciphertext output of those 64 zero bits.

My questions are then:

  • With the encryption of the Temporary Data with 64 bits of plaintext known, does this allow an attacker to brute force the password and know when they got a plausible password because the decryption of the Temporary Data with AES and the derived key they are currently trying will result in 64 bits in the middle being zero which is statistically unlikely?

  • Can a cryptanalyst retrieve the full Password Derived Key more easily now that it has been used to encrypt multiple blocks in AES-ECB, some of which has known plaintext? How? And does this mean they could use that recovered Password Derived Key to decrypt the Master Key?

  • Can a cryptanalyst use the known encryption of the zero bits in the Temporary Data to recover the Master Key with less effort (perhaps using a known plaintext attack, differential cryptanalysis or two-time pad type recovery)?

  • What other cryptanalysis is possible if a cryptanalyst has access to this information?

$\endgroup$
1
$\begingroup$

With the encryption of the Temporary Data with 64 bits of plaintext known, does this allow an attacker to brute force the password and know when they got a plausible password because the decryption of the Temporary Data with AES and the derived key they are currently trying will result in 64 bits in the middle being zero which is statistically unlikely?

Yes. The attacker tries plausible passwords starting from most likely (1234, test), runs each thru the password KDF to get the corresponding Password Derived Key, use that to decipher the temporary data, and check that the appropriate 64 bits are zero. If that's the case, the right password has likely been found. This is selective enough that for a fair quality password (says 48-bit, more than XKCD propose), probability of false positive are low ($\approx2^{48-64}<1/65000$). Because there is no salt, the cost of the password KDF (if sizable entropy stretching is used) is incurred only once per password, regardless of the number of users (each user targeted add obly one AES decryption and test).

Does this mean they could use that recovered Password Derived Key to decrypt the Master Key?

Yes, and from that the "data on the service".


With what we know, I see no other attack, and it is unclear what's the baseline for "more easily" and "less effort" in the question. Forget about brute-forcing AES-128. If there was known plaintext or redundancy in "data on the service", that could help (e.g. to confirm the password), but won't change the overall attack cost, which depends mostly on the password KDF and its parametrization; and the user choosing a hard-to-guess password.

$\endgroup$
  • $\begingroup$ Thanks for your answer, it confirms my suspicion. However, are you sure there is absolutely no cryptanalysis possible to find the Master Key directly with cryptanalysis (due to multiple blocks being encrypted with AES-ECB using the same key and the second block having 64 bits of known plaintext)? That was the main essence of my question because I read AES-ECB is insecure if used to encrypt multiple blocks with the same key. I am wondering what is the computational effort required to recover the Master Key in that scenario? Also what cryptanalysis method would be used? $\endgroup$ – aesec Feb 14 '18 at 22:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.