Home >Web Front-end >JS Tutorial >Solution to the inconsistency between AES encryption and other languages ​​in Node.js_javascript skills

Solution to the inconsistency between AES encryption and other languages ​​in Node.js_javascript skills

WBOY
WBOYOriginal
2016-05-16 16:56:151650browse

Example 1:

I have been troubled by a problem these days. The AES encryption of Nodejs is inconsistent with the encryption of Java and C#. Of course, this cannot be decrypted. I struggled for a long time: I finally couldn’t do it anymore, so I took a look at the source code, otherwise I would have to continue to struggle. It is said on the Internet that the usual nodejs AES implementation is different from other languages. Okay~~maybe.
crypto module for nodejs.

Copy code The code is as follows:

var crypto = require('crypto') ;

var data = "156156165152165156156";
console.log('Original cleartext: ' data);
var algorithm = 'aes-128-ecb';
var key = '78541561566';
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 ' ciphertext: ' cipherChunks.join(''));
/*decryption*/
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, no Wrong~~Encryption and decryption were successful. But it is different from the encryption in Java and C#. God. I think everyone is struggling here, right? In fact, as long as we add a vector, it will be consistent. There are too few resources found online. That’s why I struggled with it for so long. Well, the correct code is:
Copy the code The code is as follows:

var crypto = require('crypto');

var data = "156156165152165156156";
console.log('Original cleartext: ' data);
var algorithm = 'aes-128-ecb';
var key = '78541561566';
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 ' ciphertext: ' 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(''));


Comparison found that, The encryption is consistent. Okay, knot~~~ I hate you for wasting my day.


Example 2:

At work, I encountered nodejs encryption through AES and Android client Java decryption. I agreed that nodejs also needs to decrypt the content encrypted by the Android client. I found that the two encryption results were different. After querying the data, I found that the Java side needs to za the key. Encrypt again with MD5. The following is the content of aes ecb encryption. If it is cbc, you also need to encrypt the secret key MD5:


nodejs:

Copy code 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:
复制代码 代码如下:

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"; 

    /**
     * 解密
     * @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); 
    } 

    /**
     * 加密
     * @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); 
    } 

    /**
* Convert 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; 
    } 

    /**
* Bytes 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", "1234fghjnmlkiuhA")); 
        System.out.println(AESForNodejs.decrypt("5b8e85b7a86ad15a275a7cb61fe4c0606005e8741f68797718a3e90d74b5092a", "1234fghjnmlkiuhA")); 
    } 
}
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn