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 (
"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?