Reputation: 13
I am currently trying to port the following code from Java using BouncyCastle to NodeJs using CryptoJS (but I am open to use a different lib for NodeJS).
The only important thing, is that the result of the code is the same.
Java:
import java.security.Security;
import javax.xml.bind.DatatypeConverter;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.Mac;
import org.bouncycastle.crypto.engines.AESFastEngine;
import org.bouncycastle.crypto.macs.CMac;
import org.bouncycastle.crypto.params.KeyParameter;
public class MainIntel {
public static void main(String args[]) {
Security.addProvider(new BouncyCastleProvider());
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
System.out.println("Bouncy Castle provider is NOT available");
} else {
byte[] kSdm = toByteArray("00000000000000000000000000000000");
System.out.println(toHexString(kSdm));
byte[] sv2 = toByteArray("3CC30001008004DE5F1EACC0403D0000");
System.out.println(toHexString(sv2));
byte[] kSes = calculateMFCMAC(kSdm, sv2);
System.out.println(toHexString(kSes));
}
}
public static String toHexString(byte[] array) {
return DatatypeConverter.printHexBinary(array);
}
public static byte[] toByteArray(String s) {
return DatatypeConverter.parseHexBinary(s);
}
public static byte[] calculateMFCMAC(byte[] key, byte[]
valueToMAC) {
try {
int cmacSize = 16;
BlockCipher cipher = new AESFastEngine();
Mac cmac = new CMac(cipher, cmacSize * 8);
KeyParameter keyParameter = new KeyParameter(key);
cmac.init(keyParameter);
cmac.update(valueToMAC, 0, valueToMAC.length);
byte[] CMAC = new byte[cmacSize];
cmac.doFinal(CMAC, 0);
return CMAC;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
}
This code gives the following output:
00000000000000000000000000000000
3CC30001008004DE5F1EACC0403D0000
3FB5F6E3A807A03D5E3570ACE393776F
NodeJs:
const CryptoJS = require('crypto-js');
const kSdm = '00000000000000000000000000000000';
console.log(kSdm);
const sv2 = '3CC30001008004DE5F1EACC0403D0000';
console.log(sv2);
const kSes = encrypt(kSdm, sv2);
console.log(kSes);
function encrypt(key, data) {
const ciphertext = CryptoJS.AES.encrypt(
CryptoJS.enc.Hex.parse(data),
CryptoJS.enc.Hex.parse(key),
{
padding: CryptoJS.pad.NoPadding,
mode: CryptoJS.mode.CBC,
iv: CryptoJS.enc.Hex.parse(key)
},
).toString();
return Buffer.from(ciphertext, 'base64').toString('hex');
}
But this code gives me:
00000000000000000000000000000000
3CC30001008004DE5F1EACC0403D0000
42808a1bc75ba899a50471b1c6c1bbe3
NodeJs - Option 2:
var key = new Buffer('00000000000000000000000000000000', 'hex');
var src = new Buffer('3CC30001008004DE5F1EACC0403D0000', 'hex');
cipher = crypto.createCipheriv('aes-128-cbc', key, Buffer.alloc(0));
cipher.setAutoPadding(false);
result = cipher.update(src).toString('hex');
result += cipher.final().toString('hex');
console.log(result);
also gives me:
42808a1bc75ba899a50471b1c6c1bbe3
So the resulting outputs
differ.
Anyone an idea how I could solve that? Like I said, I am open to use any other NodeJS crypto lib like jsrsasign, etc.
Thanks for your help :)
Upvotes: 1
Views: 1262
Reputation: 710
crypto-js
doesn't implement AES-CMAC algorithm, so you are getting a different result.
There's one that i found node-aes-cmac. Using this, i got the expected output.
Code for refernce:
var aesCmac = require('node-aes-cmac').aesCmac;
// Example with buffers.
var bufferKey = Buffer.from('00000000000000000000000000000000', 'hex');
var bufferMessage = Buffer.from('3CC30001008004DE5F1EACC0403D0000','hex');
var options = {returnAsBuffer: true};
cmac = aesCmac(bufferKey, bufferMessage, options);
console.log("cmac "+ Buffer.from(cmac, 'base64').toString('hex')) ;
**Output**
cmac 3fb5f6e3a807a03d5e3570ace393776f
Upvotes: 2