我正在使用第三方API,在该API中,我必须以aes-128加密形式发送数据。为了帮助您进行加密/解密,他们给了我Java代码。我试图在Node.js中复制它,但是我无法像普通的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);
答案 0 :(得分:0)
已弃用的crypto.createCipher
函数(如API文档中所述),从提供的密码中导出加密密钥:
crypto.createCipher()
的实现使用OpenSSL函数EVP_BytesToKey
导出密钥,摘要算法设置为 MD5,一次迭代,并且没有盐。缺少盐会使字典受到攻击,因为相同的密码始终会创建相同的密钥。低迭代次数和非加密安全的哈希算法可以非常快速地测试密码。
例如这样的例子:
var crypto = require( 'crypto' );
var cipher = crypto.createCipheriv( 'aes-192-cbc', encryptionKey, Buffer.from(iv) );
var buf1 = cipher.update( Buffer.from(data) );
var buf2 = cipher.final();
var encrypted = Buffer.concat([buf1, buf2]);