gpt4 book ai didi

javascript - 在node.js中使用加密的aes-128-cbc加密/解密没有给出与java代码相同的结果

转载 作者:行者123 更新时间:2023-12-02 23:17:09 28 4
gpt4 key购买 nike

我正在使用第三方 API,其中我必须以 aes-128 加密形式发送数据。为了帮助加密/解密,他们给了我 java 代码。我尝试在 Node.js 中复制它,但我无法应用与 pergive java 代码相同的加密,因此我遇到了错误。

java中的工作代码是 -

public class AesCryptUtil {
Cipher ecipher;
/**
* Input a string that will be md5 hashed to create the key.
*
* @return void, cipher initialized
*/
public AesCryptUtil() {
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
this.setupCrypto(kgen.generateKey());
} catch (Exception e) {
e.printStackTrace();
}
}

public AesCryptUtil(String key) {
SecretKeySpec skey = new SecretKeySpec(getMD5(key), "AES");
this.setupCrypto(skey);
}

private void setupCrypto(SecretKey key) {
// Create an 8-byte initialization vector
byte[] iv = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };

AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
try {
ecipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

// CBC requires an initialization vector
ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
} catch (Exception e) {
e.printStackTrace();
}
}

// Buffer used to transport the bytes from one stream to another
byte[] buf = new byte[1024];

public void encrypt(InputStream in, OutputStream out) {
try {
// Bytes written to out will be encrypted
out = new CipherOutputStream(out, ecipher);

// Read in the cleartext bytes and write to out to encrypt
int numRead = 0;
while ((numRead = in.read(buf)) >= 0) {
out.write(buf, 0, numRead);
}
out.close();
} catch (java.io.IOException e) {
e.printStackTrace();
}
}
/**
* Input is a string to encrypt.
*
* @return a Hex string of the byte array
*/
public String encrypt(String plaintext) {
try {
byte[] ciphertext = ecipher.doFinal(plaintext.getBytes("UTF-8"));
return this.byteToHex(ciphertext);
} catch (Exception e) {
e.printStackTrace();
return null;
}

}


/**
* Input encrypted String represented in HEX
**/

private static byte[] getMD5(String input) {
try {
byte[] bytesOfMessage = input.getBytes("UTF-8");
MessageDigest md = MessageDigest.getInstance("MD5");
return md.digest(bytesOfMessage);
} catch (Exception e) {
return null;
}
}

static final String HEXES = "0123456789ABCDEF";

public static String byteToHex(byte[] raw) {
if (raw == null) {
return null;
}
String result = "";
for (int i = 0; i < raw.length; i++) {
result += Integer.toString((raw[i] & 0xff) + 0x100, 16).substring(1);
return result;
}

public static byte[] hexToByte(String hexString) {
int len = hexString.length();
byte[] ba = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
ba[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
+ Character.digit(hexString.charAt(i + 1), 16));
}
return ba;
}

public static void main(String args[]) {
String result = null;
String err = null;
String key = "DEEA29E294D8B2241FB41EF254AAB86F";
String data = "<?xml version=" + "1.0" + " encoding=" + "UTF-8" + "?><xmltagopen></xmltagclose>";
String action = "enc";

if (key == null)
err = "error: no key";
else if (key.length() < 32)
err = "error: key length less than 32 bytes";
else if (data == null || action == null)
err = "error: no data";
else if (action == null)
err = "error: no action";
else if (!action.equals("enc") && !action.equals("dec"))
err = "error: invalid action";

if (err == null) {
try {
AesCryptUtil encrypter = new AesCryptUtil(key);

if (action.equals("enc"))
result = encrypter.encrypt(data);
else
result = encrypter.decrypt(data);
} catch (Exception e) {
err = "error : Exception in performing the requested operation : " + e;
}
}
if (result != null)
System.out.println(result);
else
System.out.println(err);
}

}

我尝试在 node.js 中执行类似操作,但它不起作用,并且我从 api 收到错误消息,表明加密不正确 -

const xml = '<?xml version="1.0" encoding="UTF-8"?><xmltagopen</xmltagclose>';
let key = 'DEEA29E294D8B2241FB41EF254AAB86F';
let encodeKey = crypto.createHash('md5').update(key, 'utf8').digest("hex");
console.log(encodeKey);
let ivBuffer = new Buffer.from([0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f]);
let iv = ivBuffer.toString('hex');

let cipher = crypto.createCipher('aes-128-cbc', encodeKey, iv);
let encText = cipher.update(xml, 'utf8', 'hex');
encText += cipher.final('hex');
console.log(encText);

最佳答案

已弃用的 crypto.createCipher函数,如 API 文档中所述,从提供的密码派生加密 key :

The implementation of crypto.createCipher() derives keys using the OpenSSL function EVP_BytesToKey with the digest algorithm set to MD5, one iteration, and no salt. The lack of salt allows dictionary attacks as the same password always creates the same key. The low iteration count and non-cryptographically secure hash algorithm allow passwords to be tested very rapidly.

使用crypto.createCipheriv相反。

例如这样:

var crypto  = require( 'crypto' );
var encryptionKey = Buffer.from('DEEA29E294D8B2241FB41EF254AAB86F', 'hex');
var iv = Buffer.from([0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f]);
// better: var iv = crypto.randomBytes(16);
var cipher = crypto.createCipheriv( 'aes-128-cbc', encryptionKey, iv );
var buf1 = cipher.update( Buffer.from(data) );
var buf2 = cipher.final();
var encrypted = Buffer.concat([buf1, buf2]);

关于javascript - 在node.js中使用加密的aes-128-cbc加密/解密没有给出与java代码相同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57123473/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com