I'm a pentester and currently analysing a web application which are using some strange encryption scheme.

The point is: They encrypt using AES-128, generate a (not cryptographic secure) key and use this as encryption key AND initialization vector.

I'm not a crypto expert, but I know that this is bad (aside of the insecure generation of the key). The problem is, that I don't know what the concrete consequences are?

Can someone please enlighten me, so I can explain to the developers that this is bad? Thanks


4 Answers 4


CBC mode encrypts as follows: $$ C_0 = E_K(IV\oplus P_0);\\ C_i = E_K(C_{i-1}\oplus P_i), $$ where $P_i$ are plaintext blocks and $C_i$ are ciphertext blocks. Traditionally, IV must be random and is published alongside the ciphertext to enable decryption. If it is also published in your case, then this reveals the key and is trivially insecure.

If the $IV=K$ is not attached to the ciphertext, then you get a deterministic (in contrast to probabilistic) encryption scheme. It has a number of insecure properties, such as

  • the ciphertext does not change if the same plaintext is encrypted multiple times.
  • if two plaintexts have the same prefix, then the ciphertexts will have the same property.

Maybe there are others, but these ones are sufficient to avoid using such scheme to protect confidentiality of any reasonable amount of data, except maybe for very short (16 bytes or less) plaintexts.

  • 1
    $\begingroup$ Said otherwise: this is bad if the same key is used for several messages that have fair chance to start with the same 16 bytes, for examining ciphertext reveals when that's the case, and (in that event) if the next 16 bytes of the message are the same. $\endgroup$
    – fgrieu
    Commented May 14, 2014 at 13:05

This usage is very insecure as it can leak the AES KEY (If decryption is allowed). Consider this case where the server prints the decrypted text. The attacker can modify the $C_i$ to recover the $IV$, and in this case yields the secret $K$. Assume three blocks of plaintext is encrypted to get \begin{align} C_0 &= E_K(IV\oplus P_0); \\ C_1 &= E_K(C_0\oplus P_1); \\ C_2 &= E_K(C_1\oplus P_2); \\ \end{align}

The attacker can now modify the ciphertext as following $$ C'_0=C_0; \quad C'_1=0; \quad C'_2=C_0; $$ and pass it to the decryption oracle, which will indeed return \begin{align} P_0 &= IV\oplus D_K(C'_0); \\ P_1 &= C'_0\oplus D_K(0); \\ P_2 &= 0\oplus D_K(C'_0); \\ \end{align}

As you can see, the $K$ is nothing but the $XOR$ of $P_0$ and $P_2$:

\begin{align} P_0\oplus P_2 &= IV\oplus D_K(C'_0)\oplus D_K(C'_0)\\ &= IV = K \end{align}

This idea is developed from the concept of IV recovery in AES CBC mode.

  • 3
    $\begingroup$ The same attack can be done with two blocks of ciphertext too! $\endgroup$ Commented Feb 11, 2019 at 13:41
  • 1
    $\begingroup$ thank you so much your answer was exactly what I was looking for $\endgroup$ Commented May 20, 2021 at 15:23

If they are not generating a new key for every encryption, then the other answers apply.

If they are generating a new random key for every encryption, then there are no glaring security holes (since they are using a poor random number generator, even if they think they are generating new keys for every encryption, they might not be).

That said, if they are generating a new key for every encryption and switch to a good random number generator, you should still try to talk them out of doing what they are doing. The reason being, they are not following the well-studied standards. No cryptanalyst that I am aware of has studied the particular construction they are (potentially) using (key==iv, iv not sent in the clear, new random key for every encryption). So, there might be unknown weaknesses. Why not use standard practices and at least know that lots of people have studied your construction and have not found problems.


As long as the IV is not published as it usually is with CBC in the first crypt text block (I assume you wouldn't have asked in that case), the main problem I see is that encryption is deterministic, that means if you encrypt the same plain text twice you will get the same cipher text twice. As CBC works by iterating the through the plain text in blocks that also translate to full block prefixes. Remember that a block is only 16 bytes long with AES128. For many applications these are only 16 characters out of a small charset.

This is especially problematic if the service offers an encryption oracle in some form or another, i.e. you can feed it values that will be encrypted using the secret key. In that case you can test blocks against the first block until you find the correct value. In some applications the entropy of the data that is to be encrypted is low enough to find the original value.

Even if there is no encryption oracle when the messages have low entropy you can still gain the information which messages share the same prefixes and which don't. Imagine for example some ajax requests that only access 6 different urls:

GET /appA/routine1 HTTP/1.1
GET /appA/routine2 HTTP/1.1
GET /appA/routine3 HTTP/1.1
GET /appB/callA HTTP/1.1
GET /appB/callB HTTP/1.1
GET /error HTTP/1.1

Split them up in blocks and you will get:

GET /appA/routin     e1 HTTP/1.1\nHos     …
GET /appA/routin     e2 HTTP/1.1\nHos     …
GET /appA/routin     e3 HTTP/1.1\nHos     …
GET /appB/callMy     A HTTP/1.1\nHost     …
GET /appB/callMy     B HTTP/1.1\nHost     …
GET /error HTTP/     1.1\nHost: www.e     …

Or more abstractly the following pattern:


Without even knowing any other information you can identify which calls were made to /appA, /appB and which to /error just by observing the crypt text patterns.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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