我正在尝试将Java代码转换为NodeJs代码。
在加密方面面临一些问题。
这是我的Java代码:compiled code

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.util.Base64;

public class AESCBCPKCS5Encryption {
    private static final String ALGORITHM = "AES/CBC/PKCS5Padding";

    public static String encrypt(String message, String key) throws GeneralSecurityException, UnsupportedEncodingException {
        if (message == null || key == null) {
            throw new IllegalArgumentException("text to be encrypted and key should not be null");
        }
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        byte[] messageArr = message.getBytes();
        SecretKeySpec keySpec = new SecretKeySpec(Base64.getDecoder().decode(key), "AES");
        byte[] ivParams = new byte[16];
        byte[] encoded = new byte[messageArr.length + 16];
        System.arraycopy(ivParams, 0, encoded, 0, 16);
        System.arraycopy(messageArr, 0, encoded, 16, messageArr.length);
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(ivParams));
        byte[] encryptedBytes = cipher.doFinal(encoded);
        encryptedBytes = Base64.getEncoder().encode(encryptedBytes);
        return new String(encryptedBytes);
    }

    public static String decrypt(String encryptedStr, String key) throws GeneralSecurityException, UnsupportedEncodingException {
        if (encryptedStr == null || key == null) {
            throw new IllegalArgumentException("text to be decrypted and key should not be null");
        }
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        SecretKeySpec keySpec = new
                SecretKeySpec(Base64.getDecoder().decode(key), "AES");
        byte[] encoded = encryptedStr.getBytes();
        encoded = Base64.getDecoder().decode(encoded);
        byte[] decodedEncrypted = new byte[encoded.length - 16];
        System.arraycopy(encoded, 16, decodedEncrypted, 0, encoded.length - 16);
        byte[] ivParams = new byte[16];
        System.arraycopy(encoded, 0, ivParams, 0, ivParams.length);
        cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(ivParams));
        byte[] decryptedBytes = cipher.doFinal(decodedEncrypted);
        return new String(decryptedBytes);
    }

    public static void main(String[] args) throws GeneralSecurityException, UnsupportedEncodingException {
        String str = "<Request xmlns=\"http://www.kotak.com/schemas/CorpCCPaymentsOTP/CorpCCPaymentsOTP.xsd\" ><username>ENKASH</username><password>Corp@123</password><SrcAppCd>ENKA SH</SrcAppCd><RefNo>Ref1111111111</RefNo><CardNo>4280933990002698</CardNo ><OTP>12345</OTP></Request>";
        String key = "e3a74e3c7599f3ab4601d587bd2cc768";
        String enc = encrypt(str, key);
        System.out.println(enc);
        String dec = decrypt(enc, key);
        System.out.println(dec);
    }
}


这是我的JavaScript代码:

var crypto = require('crypto');

function getAlgorithm(keyBase64) {

    var key = Buffer.from(keyBase64, 'base64');
    switch (key.length) {
        case 16:
            return 'aes-128-cbc';
        case 32:
            return 'aes-256-cbc';

    }

    throw new Error('Invalid key length: ' + key.length);
}


function encrypt(plainText, keyBase64, ivBase64) {

    const key = Buffer.from(keyBase64, 'base64');
    const iv  = Buffer.from(ivBase64, 'base64');

    const cipher  = crypto.createCipheriv(getAlgorithm(keyBase64), key, iv);
    let encrypted = cipher.update(plainText, 'utf8', 'base64');
    encrypted += cipher.final('base64');
    return encrypted;
}

function decrypt(messagebase64, keyBase64, ivBase64) {

    const key = Buffer.from(keyBase64, 'base64');
    const iv  = Buffer.from(ivBase64, 'base64');

    const decipher = crypto.createDecipheriv(getAlgorithm(keyBase64), key, iv);
    let decrypted  = decipher.update(messagebase64, 'base64');
    decrypted += decipher.final();
    return decrypted;
}


var keyBase64 = "DWIzFkO22qfVMgx2fIsxOXnwz10pRuZfFJBvf4RS3eY=";
var ivBase64  = 'e3a74e3c7599f3ab4601d587bd2cc768';
var plainText = '<Request xmlns="http://www.kotak.com/schemas/CorpCCPaymentsOTP/CorpCCPaymentsOTP.xsd"><username>ENKASH</username><password>Corp@123</password><SrcAppCd>ENKA SH</SrcAppCd><RefNo>Ref1111111111</RefNo><CardNo>4280933990002698</CardNo ><OTP>12345</OTP></Request>';

var cipherText          = encrypt(plainText, keyBase64, ivBase64);
var decryptedCipherText = decrypt(cipherText, keyBase64, ivBase64);

console.log('Algorithm: ' + getAlgorithm(keyBase64));
console.log('Plaintext: ' + plainText);
console.log('Ciphertext: ' + cipherText);
console.log('Decoded Ciphertext: ' + decryptedCipherText);


加密引发错误,
我在这里做错了什么?

最佳答案

AES模式下CBC的初始化向量长度为​​16字节,JAVA中的代码使用前16个字节的IV,但是对于node.js代码,它使用了所有24字节的IV,因此会出错。试试这个代码

var crypto = require('crypto');

function getAlgorithm(keyBase64) {

    var key = Buffer.from(keyBase64, 'base64');
    switch (key.length) {
        case 16:
            return 'aes-128-cbc';
        case 32:
            return 'aes-256-cbc';

    }

    throw new Error('Invalid key length: ' + key.length);
}


function encrypt(plainText, keyBase64, ivBase64) {

    const key = Buffer.from(keyBase64, 'base64');
    const iv  = Buffer.from(ivBase64, 'base64');

    const cipher  = crypto.createCipheriv(getAlgorithm(keyBase64), key, iv.slice(0, 16));
    let encrypted = cipher.update(plainText, 'utf8', 'base64');
    encrypted += cipher.final('base64');
    return encrypted;
}

function decrypt(messagebase64, keyBase64, ivBase64) {

    const key = Buffer.from(keyBase64, 'base64');
    const iv  = Buffer.from(ivBase64, 'base64');

    const decipher = crypto.createDecipheriv(getAlgorithm(keyBase64), key, iv.slice(0, 16));
    let decrypted  = decipher.update(messagebase64, 'base64');
    decrypted += decipher.final();
    return decrypted;
}


var keyBase64 = "DWIzFkO22qfVMgx2fIsxOXnwz10pRuZfFJBvf4RS3eY=";
var ivBase64  = 'e3a74e3c7599f3ab4601d587bd2cc768';
var plainText = '<Request xmlns="http://www.kotak.com/schemas/CorpCCPaymentsOTP/CorpCCPaymentsOTP.xsd"><username>ENKASH</username><password>Corp@123</password><SrcAppCd>ENKA SH</SrcAppCd><RefNo>Ref1111111111</RefNo><CardNo>4280933990002698</CardNo ><OTP>12345</OTP></Request>';

var cipherText          = encrypt(plainText, keyBase64, ivBase64);
var decryptedCipherText = decrypt(cipherText, keyBase64, ivBase64);

console.log('Algorithm: ' + getAlgorithm(keyBase64));
console.log('Plaintext: ' + plainText);
console.log('Ciphertext: ' + cipherText);
console.log('Decoded Ciphertext: ' + decryptedCipherText);

关于javascript - NodeJ中的AES/CBC/PKCS5Padding,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59788079/

10-09 20:28