Sample implementation of java CBCBlockCipherMac in Objective c

877 Views Asked by At

Can anyone share a sample code on how to implement CBCBlockCipherMac in objective C. here is how far I got and its giving a different result from the java implementation.

const unsigned char key[16] = "\x1\x2\x3\x4\x5\x6\x7\x8\x9\x0\x1\x2\x3\x4\x5\x6";
const unsigned char data[14] = "\x54\x68\x69\x73\x69\x73\x6d\x79\x73\x74\x72\x69\x6e\x67";

CMAC_CTX *ctx = CMAC_CTX_new();
ret = CMAC_Init(ctx, key, sizeof(key), EVP_des_ede3(), 0);


printf("CMAC_Init = %d\n", ret);

ret = CMAC_Update(ctx, data, sizeof(data));

printf("CMAC_Update = %d\n", ret);

size_t size;
//unsigned int size;
unsigned char tag[4];
ret = CMAC_Final(ctx, tag, &size);


printf("CMAC_Final = %d, size = %u\n", ret, size);

CMAC_CTX_free(ctx);

printf("expected: 391d1520\n"
       "got:      ");
size_t index;
for (index = 0; index < sizeof(tag) - 1; ++index) {
    printf("%02x", tag[index]);
    if ((index + 1) % 4 == 0) {
        printf(" ");
    }
}
printf("%02x\n", tag[sizeof(tag) - 1]);

And my java code looks like this

String *data = "Thisismystring";
String *keyString = "1234567890123456";


bytes[]mac = new byte[4];
CBCBlockCipherMac macCipher = new CBCBlockCipherMac(DESedeEngine);
DESedeParameters keyParameter = new DESedeParameters(keyString.getBytes());
DESedeEngine engine = new DESedeEngine();
engine,init(true, keyParameter);
byte[] dataBytes = data.getBytes();
macCipher.update(dataBytes,0,data.length());
macCipher.doFinal(mac,0);
byte[] macBytesEncoded = Hex.encode(mac);
String macString = new String(macBytesEncoded);

This gives me "391d1520". But the objective c gives me "01000000"

1

There are 1 best solutions below

4
On

CMAC is not the same as CBC MAC. CMAC has an an additional step at the beginning and the end of the calculation. If possible I would suggest you upgrade your Java code to use CMAC, as CBC is not as secure, e.g. using org.bouncycastle.crypto.macs.CMac.

OpenSSL does not seem to implement CBC MAC directly (at least, I cannot find any reference to it). So if you need it, you need to implement it yourself.

You can use CBC mode encryption with a zero IV and take the last 16 bytes of the encryption. Of course, this means you need to store the rest of the ciphertext in a buffer somewhere, or you need to use the update functions smartly (reusing the same buffer over and over again for the ciphertext).