3

I have a basic protocol which tries to authenticate messages going from client to server. Basically it is like this:

Imagine I want to send message M to server. Client computes a MAC over the message. The MAC is basically DES_ECB encryption of data MAC_DATA length of which is 8 bytes. MAC_DATA is obtained by XORING the plain message M between each other. Like this

  for (int i = 0; i < dwSize; i += DppGlobals.MAC_SIZE)
  {
        for (int j = 0; j < DppGlobals.MAC_SIZE; j++)
           MAC_DATA[j] ^= plaindata[i + j];
  }

And MAC is

  CALC_MAC = DppDES.EncryptDES_ECB(MAC_DATA, WorkKey);

Finally what client sends to server is:

Client -> Server: CALC_MAC, M

Assume keys are stored securely on client and server, and also they are shared. Now since DES is insecure I am trying to improve this protocol. My idea is basically the client will send to server AES encryption of the data it was sending before. So client sends to server

   Client -> Server:  C

Where C = AES_ENCRYPT_CBC(CAL_MAC | M, Key, someIV);

The server will decrypt the data it receives, and perform computations like it was doing before.

So is my modified version (with AES encryption) more secure than the old(current) protocol?

Since this protocol is already implemented, the change I want to add for improving its security should desirably be minimal - to avoid introducing new bugs. Also completely rewriting and using TLS is not an option.

1 Answers1

1

The original is completely broken and would be regardless of the insecurity of DES.

The ECB encryption of a single block message (with a secure cipher) would be a secure MAC, but XORing the message blocks means that an attacker can modify any block of the message simply by making the same change to another block so that they cancel out.

The modified protocol is better, but not necessarily secure. For example, if the attacker can see two messages whose last blocks are "compatible" so that switching one for the other does not affect the aggregate XOR, the attacker can make that change knowing the MAC will match. I think this scheme effectively reduces to hash-then-encrypt (with an insecure hash, even), which is not secure. Even better attacks may exist.

You would be better off with an actual MAC algorithm. For example CMAC, if it must use a block cipher.

A minimal change would be to rip out all the current MAC code and replace it with just sending M, AES-CBC-MAC(len(M) || M), where len(M) is the length of the message as a 64-bit integer and || is concatenation. This would be secure authentication, but would of course not hide the message.

otus
  • 32,132
  • 5
  • 70
  • 165
  • It would require lot of change in existing code to replace original MAC with CMAC. If I use strong AES encryption instead as in my example, how secure is that? –  Nov 18 '15 at 13:20
  • @user200312, probably not very. The linked question shows some attacks, but even worse attacks could be possible here, because XOR is so simple to find collisions for. If you know messages to be of fixed length, you could use CBC-MAC, which ought to be even easier to integrate than your idea. – otus Nov 18 '15 at 13:23
  • @user200312, if lengths are fixed you can just replace the old CALC_MAC thing with CBC-MAC. If not, you could use one of the secure variants. – otus Nov 18 '15 at 13:25
  • Lengths are fixed you say, which length? length of current mac is 8 bytes –  Nov 18 '15 at 13:25
  • @user200312, just use length-prepended CBC-MAC with AES, unless you need encryption to hide the messages. The encryption layer does not generally result in secure authentication if the MAC is not already secure. And yes, the XOR should go. – otus Nov 18 '15 at 13:32
  • also what is length of CBC-MAC output? –  Nov 18 '15 at 13:53
  • @user200312, basically the idea is that the last block of CBC encryption is $C' = E(C \oplus P)$, so if the attacker can find two messages where $C_1 \oplus C_2 \oplus P_2$ and $P_1$ have the same XOR of the 64-bit halves, they can replace $C_1'$ with $C_2'$ without affecting the "MAC". It is expendable to longer postfixes, which means it is more likely than just a random 64-bit collision per message. Again, that's just an attack I could immediately see, there may be easier ones. CBC-MAC output length is the block size, so 128 bits for AES. – otus Nov 18 '15 at 14:19
  • should len(M) be encoded in binary or as string? –  Nov 18 '15 at 16:05
  • @user200312, binary, that's why I suggested 64-bit. String encodings can be each others' prefixes which brings back the attack that applies on normal CBC-MAC. (There are other ways to solve it, but a fixed width length field is the easiest.) – otus Nov 18 '15 at 16:56
  • Wiki of CBC MAC says length should be prepended as first block. Block length of AES is 128 bits. How come 64 bit integer then as you suggest? –  Nov 18 '15 at 18:01
  • @user200312, it says "in the first block". Any constant integer size is fine, since it prevents different length messages from starting the same. I suggested 64 bits because it is usually large enough and supported in most computing environments. – otus Nov 18 '15 at 21:12
  • So it should be number encoded as 128 integer? or 64 bit integer, with other 64 bits padded as zeros? I guess endianness doesn't matter. Now, struggling to find some simple reliable aes class in c/c++ :( also is the attack you describe on my original protocol with des, practical? –  Nov 18 '15 at 21:15
  • @user200312, any length and endianness works as long as you define it and do not change it. The attack on the original DES variant is definitely practical. – otus Nov 18 '15 at 21:16
  • So I can make it 64 bit integer and since block length is 128 other 64 bits I will pad with 0? –  Nov 18 '15 at 21:18
  • Please have a look here: http://crypto.stackexchange.com/questions/32883/creating-a-message-authentication-scheme (it is related to this discussion) –  Feb 18 '16 at 10:48