This article describes how to solve the inconsistency between AES encryption and other languages in Node. js. For example, if you need to communicate with C # and JAVA, refer
Example 1:
These days have been plagued by a problem. The AES encryption of Nodejs is inconsistent with that encrypted by Java and C. Of course, you cannot decrypt it. Tangle for a long time: Later, it was not enough. I read the source code, or else I had to continue to struggle. On the Internet, nodejs AES is usually implemented differently from other languages. Okay ~~ Maybe.
Nodejs crypto module.
The Code is as follows:
Var crypto = require ('crypto ');
Var data = "156156165152165156156 ";
Console. log ('original cleartext: '+ data );
Var algorithm = 'aes-128-ecb ';
Var key = '000000 ';
Var clearEncoding = 'utf8 ';
// Var cipherEncoding = 'hex ';
// If the next line is uncommented, the final cleartext is wrong.
Var cipherEncoding = 'base64 ';
/* Encryption */
Var cipher = crypto. createCipher (algorithm, key );
Var cipherChunks = [];
CipherChunks. push (cipher. update (data, clearEncoding, cipherEncoding ));
CipherChunks. push (cipher. final (cipherEncoding ));
Console. log (cipherEncoding + 'herhertext: '+ cipherChunks. join (''));
/* Decrypt */
Var decipher = crypto. createDecipher (algorithm, key );
Var plainChunks = [];
For (var I = 0; I <cipherChunks. length; I ++ ){
PlainChunks. push (decipher. update (cipherChunks [I], cipherEncoding, clearEncoding ));
}
PlainChunks. push (decipher. final (clearEncoding ));
Console. log ("UTF8 plaintext deciphered:" + plainChunks. join (''));
Indeed, that's right ~~ Encryption and decryption are successful. But it is different from that encrypted in java and C. God. I think everyone is struggling here ~~ Right. In fact, you only need to add a vector to make it consistent. Too few resources are found on the Internet. It takes so long for you to struggle. Okay,
The correct code is:
The Code is as follows:
Var crypto = require ('crypto ');
Var data = "156156165152165156156 ";
Console. log ('original cleartext: '+ data );
Var algorithm = 'aes-128-ecb ';
Var key = '000000 ';
Var clearEncoding = 'utf8 ';
Var iv = "";
// Var cipherEncoding = 'hex ';
// If the next line is uncommented, the final cleartext is wrong.
Var cipherEncoding = 'base64 ';
Var cipher = crypto. createCipheriv (algorithm, key, iv );
Var cipherChunks = [];
CipherChunks. push (cipher. update (data, clearEncoding, cipherEncoding ));
CipherChunks. push (cipher. final (cipherEncoding ));
Console. log (cipherEncoding + 'herhertext: '+ cipherChunks. join (''));
Var decipher = crypto. createDecipheriv (algorithm, key, iv );
Var plainChunks = [];
For (var I = 0; I <cipherChunks. length; I ++ ){
PlainChunks. push (decipher. update (cipherChunks [I], cipherEncoding, clearEncoding ));
}
PlainChunks. push (decipher. final (clearEncoding ));
Console. log ("UTF8 plaintext deciphered:" + plainChunks. join (''));
The comparison shows that the encryption is consistent. Okay, close the post ~~~ I hate you and waste my day.
Example 2:
In the work, nodejs is encrypted by aes and Android client is decrypted by java. It is agreed that nodejs also needs to decrypt the content encrypted by Android client. The two encryption results are different, data Query found that java needs to encrypt the key za with MD5 again. The following is the content encrypted by the aes ecb. If it is cbc, MD5 encryption is also required for the key:
Nodejs:
The Code is as follows:
/**
* Aes Encryption
* @ Param data
* @ Param secretKey
*/
EncryptUtils. aesEncrypt = function (data, secretKey ){
Var cipher = crypto. createCipher ('aes-128-ecb ', secretKey );
Return cipher. update (data, 'utf8', 'hex') + cipher. final ('hex ');
}
/**
* Aes decryption
* @ Param data
* @ Param secretKey
* @ Returns {*}
*/
EncryptUtils. aesDecrypt = function (data, secretKey ){
Var cipher = crypto. createDecipher ('aes-128-ecb ', secretKey );
Return cipher. update (data, 'hex', 'utf8') + cipher. final ('utf8 ');
}
Java:
The Code is as follows:
Package com. iofamily. util;
Import java. security. MessageDigest;
Import javax. crypto. Cipher;
Import javax. crypto. spec. SecretKeySpec;
/**
* AES encryption, consistent with Nodejs
* @ Author lmiky
* @ Date 2014-2-25
*/
Public class AESForNodejs {
Public static final String DEFAULT_CODING = "UTF-8 ";
/**
* Decryption
* @ Author lmiky
* @ Date 2014-2-25
* @ Param encrypted
* @ Param seed
* @ Return
* @ Throws Exception
*/
Private static String decrypt (String encrypted, String seed) throws Exception {
Byte [] keyb = seed. getBytes (DEFAULT_CODING );
MessageDigest md = MessageDigest. getInstance ("MD5 ");
Byte [] thedigest = md. digest (keyb );
SecretKeySpec skey = new SecretKeySpec (thedigest, "AES ");
Cipher dcipher = Cipher. getInstance ("AES ");
Dcipher. init (Cipher. DECRYPT_MODE, skey );
Byte [] clearbyte = dcipher. doFinal (toByte (encrypted ));
Return new String (clearbyte );
}
/**
* Encryption
* @ Author lmiky
* @ Date 2014-2-25
* @ Param content
* @ Param key
* @ Return
* @ Throws Exception
*/
Public static String encrypt (String content, String key) throws Exception {
Byte [] input = content. getBytes (DEFAULT_CODING );
MessageDigest md = MessageDigest. getInstance ("MD5 ");
Byte [] thedigest = md. digest (key. getBytes (DEFAULT_CODING ));
SecretKeySpec skc = new SecretKeySpec (thedigest, "AES ");
Cipher cipher = Cipher. getInstance ("AES/ECB/PKCS5Padding ");
Cipher. init (Cipher. ENCRYPT_MODE, skc );
Byte [] cipherText = new byte [cipher. getOutputSize (input. length)];
Int ctLength = cipher. update (input, 0, input. length, cipherText, 0 );
CtLength + = cipher. doFinal (cipherText, ctLength );
Return parseByte2HexStr (cipherText );
}
/**
* String to byte array
* @ Author lmiky
* @ Date 2014-2-25
* @ Param hexString
* @ Return
*/
Private static byte [] toByte (String hexString ){
Int len = hexString. length ()/2;
Byte [] result = new byte [len];
For (int I = 0; I <len; I ++ ){
Result [I] = Integer. valueOf (hexString. substring (2 * I, 2 * I + 2), 16). byteValue ();
}
Return result;
}
/**
* Convert byte to hexadecimal Array
* @ Author lmiky
* @ Date 2014-2-25
* @ Param buf
* @ Return
*/
Private static String parseByte2HexStr (byte buf []) {
StringBuffer sb = new StringBuffer ();
For (int I = 0; I <buf. length; I ++ ){
String hex = Integer. toHexString (buf [I] & 0xFF );
If (hex. length () = 1 ){
Hex = '0' + hex;
}
Sb. append (hex );
}
Return sb. toString ();
}
Public static void main (String [] args) throws Exception {
System. out. println (AESForNodejs. encrypt ("fsadfsdafsdafsdafsadfsadfsadf", "1234 fghjnmlkiuhA "));
System. out. println (AESForNodejs. decrypt ("encrypt", "1234 fghjnmlkiuhA "));
}
}