将Java(BouncyCastle)迁移到NodeJs(CryptoJS)。

huangapple go评论81阅读模式
英文:

Porting Java (BouncyCastle) to NodeJs (CryptoJS)

问题

以下是您要翻译的内容:

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;
    }

}

NodeJs代码(选项1):

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');
}

NodeJs代码(选项2):

var key = Buffer.from('00000000000000000000000000000000', 'hex');
var src = Buffer.from('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);

希望这对您有所帮助。

英文:

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:

<!-- begin snippet: js hide: false console: true babel: false -->

00000000000000000000000000000000
3CC30001008004DE5F1EACC0403D0000
3FB5F6E3A807A03D5E3570ACE393776F

NodeJs:

const CryptoJS = require(&#39;crypto-js&#39;);
const kSdm = &#39;00000000000000000000000000000000&#39;;
console.log(kSdm);
const sv2 = &#39;3CC30001008004DE5F1EACC0403D0000&#39;;
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, &#39;base64&#39;).toString(&#39;hex&#39;);
}

But this code gives me:

00000000000000000000000000000000
3CC30001008004DE5F1EACC0403D0000
42808a1bc75ba899a50471b1c6c1bbe3

NodeJs - Option 2:

var key = new Buffer(&#39;00000000000000000000000000000000&#39;, &#39;hex&#39;);
var src = new Buffer(&#39;3CC30001008004DE5F1EACC0403D0000&#39;, &#39;hex&#39;);
cipher = crypto.createCipheriv(&#39;aes-128-cbc&#39;, key, Buffer.alloc(0));
cipher.setAutoPadding(false);
result = cipher.update(src).toString(&#39;hex&#39;);
result += cipher.final().toString(&#39;hex&#39;);
console.log(result);

also gives me:

42808a1bc75ba899a50471b1c6c1bbe3

So the resulting outputs

  • Java: 3FB5F6E3A807A03D5E3570ACE393776F
  • NodeJS: 42808a1bc75ba899a50471b1c6c1bbe3
  • NodesJS Option 2: 42808a1bc75ba899a50471b1c6c1bbe3

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 将Java(BouncyCastle)迁移到NodeJs(CryptoJS)。

答案1

得分: 2

crypto-js 不实现AES-CMAC算法,因此你得到了不同的结果。
我找到了一个可以使用的库node-aes-cmac。使用这个库,我得到了预期的输出。

参考代码:

var aesCmac = require('node-aes-cmac').aesCmac;
 
// 以缓冲区为例。
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'));

**输出** 

cmac 3fb5f6e3a807a03d5e3570ace393776f
英文:

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(&#39;node-aes-cmac&#39;).aesCmac;
// Example with buffers.
var bufferKey = Buffer.from(&#39;00000000000000000000000000000000&#39;, &#39;hex&#39;);
var bufferMessage = Buffer.from(&#39;3CC30001008004DE5F1EACC0403D0000&#39;,&#39;hex&#39;);
var options = {returnAsBuffer: true};
cmac = aesCmac(bufferKey, bufferMessage, options);
console.log(&quot;cmac &quot;+ Buffer.from(cmac, &#39;base64&#39;).toString(&#39;hex&#39;)) ;
**Output** 
cmac 3fb5f6e3a807a03d5e3570ace393776f

huangapple
  • 本文由 发表于 2020年7月22日 02:50:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/63021203.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定