Javascript 节点中的AES加密结果与java不同

Javascript 节点中的AES加密结果与java不同,javascript,java,node.js,encryption,aes,Javascript,Java,Node.js,Encryption,Aes,我正在尝试将AES ECB加密的Java代码移植到node.js中 问题在于java和node的输出不同 下面是java代码 public static final String DEFAULT_ENCODING = "UTF-8"; public static final String SEC_PROVIDER = "SunJCE"; public static final String AES_ALGORITHM = "AES"; public static final String

我正在尝试将AES ECB加密的Java代码移植到node.js中

问题在于java和node的输出不同

下面是java代码

 public static final String DEFAULT_ENCODING = "UTF-8";
 public static final String SEC_PROVIDER = "SunJCE";
 public static final String AES_ALGORITHM = "AES";
 public static final String RIJNDAEL_CIPHER = **"Rijndael/ECB/NoPadding"**;
 public static final int **CIPHER_PAD_SIZE = 32**;
 public static final String HEX_KEY = "3b6ce332ca3b6519eac769710f41ca5c";

public static String encryptData(String text, String hexKey) throws 
    Exception {
     byte[] b1 = Hex.decodeHex(HEX_KEY.toCharArray());
     SecretKey key = new SecretKeySpec(b1, AES_ALGORITHM); 
     Cipher cipher = Cipher.getInstance(RIJNDAEL_CIPHER, SEC_PROVIDER); 
     text = padRightToMod(text, CIPHER_PAD_SIZE); 
     byte[] buf = text.getBytes(DEFAULT_ENCODING); 
     cipher.init(Cipher.ENCRYPT_MODE, key);
     buf = cipher.doFinal(buf); 
     String result = new String(Hex.encodeHex(buf)); 
     result = result.toUpperCase(); 
     return result;
}

// ensure block size of 32
public static String padRightToMod(String text, int mod) {
    if (text == null || mod <= 0) {
        return text;
    }
    final int len = text.length();
    StringBuilder buf = new StringBuilder(512);
    buf.append(text);
    for (int i = len; i % mod > 0; i++) {
        buf.append(" ");
    }
    String rs = buf.toString();
    System.out.println(rs.length());
    return rs;
}

// Call to the encrypt function 

   String encText = encryptData("Hello", HEX_KEY);
结果是 1B928CF3C18D53BA5138DD1484D181939FD2B7B2A17AE6A79664488B5C12652

==更新======

我尝试用这段代码实现github表单

const Rijndael = require("./node_modules/node-rijndael-master");
function padRightTo32(str)
{
    len=str.length;

    for(i=len; i%32>0; i++){
        str=str +" ";
    }
    console.log(str);
    console.log(str.length);
return str;
}
let key = "3b6ce332ca3b6519eac769710f41ca5c";
let original = padRightTo32("Hello");
let cipher = new Rijndael(key, "ecb");
let ciphertext = cipher.encrypt(original, 128);
console.log(ciphertext.toString("hex"));
我得到的结果是e97282fb5838a9c78e6df1f1b4aad108aa010418ec573d74b9c991f4e897e752,但不是java中Iget的加密文本。尝试256块大小也没有帮助


我缺少的是导致不同输出的内容?

关于密钥,您必须使用缓冲区将十六进制字符串转换为二进制数据(参见示例)

此外,您必须使用方法
crypto.createCipheriv
来实例化密码(参见示例)。 当前使用的(不推荐使用的)方法
crypto.creataCipher
需要一个密码,并根据密码生成密钥(参见示例)

下面的代码

crypto = require('crypto');

function encrypt(data,key) {
    var cipher = crypto.createCipheriv('aes-128-ecb', key,''); //create aes-128 cipher 
    var encrypted = cipher.update(data,'utf8', 'hex'); //output as hex
    return encrypted;
}

function padRightTo32(str) { // ensure block size of 32

    len=str.length;
    for(i=len; i%32>0; i++) {
        str=str +" ";
    }
    return str;
}

// call to encryption function
var hexKey = new Buffer('3b6ce332ca3b6519eac769710f41ca5c', 'hex'); // 16 Byte-key
encStr=encrypt(padRightTo32("Hello"),hexKey);
console.log(encStr);  
有输出吗

cc0ac95b5ffd4758dbfa40f909c285f0f86a8f19ed1a12c1bfc098348a2ac683
这等于Java代码的输出

在Java中,密钥的长度定义了使用的AES变量,例如,如果选择使用16字节密钥AES-128,如果选择32字节密钥,则使用AES-256。 在nodejs代码中,您必须明确指定AES变体,即16字节密钥的AES-128-ecb
,32字节密钥的AES-256-ecb
,等等

如注释
ECB
中所述,ECB处于非安全模式(参见示例)


我不知道
Rijndael/ECB/NoPadding
AES/ECB/NoPadding
关于Java中的密码实例化是否真的有区别。在我的测试用例中,至少结果是相同的。因此,对于nodejs代码,选择aes-128-ecb(16字节键)或aes-256-ecb(32字节键)应该有效。

Rijndael和aes不一样。为了确保256位的块大小,Java代码付出了大量的努力。AES具有128位的块大小。您没有使用相同的加密算法。还要注意,您的代码非常不安全。。。它使用ECB模式,未经过身份验证。你为什么要用这个?@LukeJoshuaPark谢谢你花时间。我认为Rijndeal是基于Wikipedia的AES。代码来自我们正在集成的供应商,我需要在“Rijndael/ECB/NoPadding”模式下对一些数据进行加密。通信将仅与白名单上的IP进行。Rijndael有许多NodeJS包。具有讽刺意味的是,他们在256位的块大小上进行了所有的努力,最终得到了128位的块和一些消息膨胀。。。这就是为什么密码应该由密码学家来完成。回答得好。@Topaco。这非常有帮助,今天我学到了一些新东西。非常感谢你。@LukeJoshuaPark也谢谢你。我猜AES毕竟是瑞恩达尔。@Narshal瑞恩达尔不是AES。。。具有128位块大小的Rijndael是AES。Rijndael还有192位和256位块大小。它们不一样。编写原始代码的开发人员认为他们使用的是256位块大小的Rijndael,但实际上他们只是将明文扩展为2 128位块的倍数,这就是为什么这个答案有效。@LukeJoshuaPark你是对的。我混淆了键大小和块大小。当我将CIPHER_PAD_SIZE设置为16时,加密和解密工作正常。我不知道为什么开发人员会采用这种方法,但我只是在评估一个产品,所以我是开放和开明的。谢谢:)
cc0ac95b5ffd4758dbfa40f909c285f0f86a8f19ed1a12c1bfc098348a2ac683