【发布时间】:2019-07-19 07:42:55
【问题描述】:
我正在尝试将用于 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);
结果是 CC0AC95B5FFD4758DBFA40F909C285F0F86A8F19ED1A12C1BFC098348A2AC683
还有这个 javascript 代码
crypto = require('crypto');
function encrypt(data,key) {
var cipher = crypto.createCipher('**aes-128-ecb**', key); //create aes 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
hexkey="3b6ce332ca3b6519eac769710f41ca5c"
encStr=encrypt(padRightTo32("Hello"),hexKey);
console.log(encStr);
结果是 1B928CF3C18D53BA5138DD1484D181939FD2B7BB2A17AE6A79664488B5C12652
==== 更新 ======
我尝试了https://github.com/Snack-X/rijndael-js 使用此代码实现 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 中得到的加密文本。尝试 256 块大小也无济于事。
我缺少什么导致不同的输出?
【问题讨论】:
-
Rijndael 和 AES 不一样。您的 Java 代码付出了很多努力来确保 256 位块大小。 AES 的块大小为 128 位。您没有使用相同的加密算法。
-
另请注意,您拥有的代码非常不安全...它使用 ECB 模式并且未经身份验证。你为什么要使用这个?
-
@LukeJoshuaPark 感谢您抽出宝贵时间。我认为 Rijndeal 是基于 Wikipedia en.wikipedia.org/wiki/Advanced_Encryption_Standard 的 AES。
-
代码来自我们正在集成的供应商,我需要在“Rijndael/ECB/NoPadding”模式下对一些数据进行加密。通信将仅使用列入白名单的 IP。
-
Rijndael 有很多 NodeJS 包。
标签: javascript java node.js encryption aes