您好,欢迎访问一九零五行业门户网

Node.js中AES加密和其它语言不一致问题解决办法_javascript技巧

例子一:
这几天被一个问题困扰着。nodejs的aes加密和java,c#加密出来的不一致。当然,这样就不能解密了。纠结了许久:后来还是实在不行了,看了下源代码,要不然还得继续纠结下去。网上说,通常的nodejs aes和其他语言实现不一样。好吧~~或许吧。
nodejs的crypto模块。
复制代码 代码如下:
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';
/*加密*/
    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(''));
/*解密*/
    var decipher = crypto.createdecipher(algorithm, key);
    var plainchunks = [];
    for (var i = 0;i       plainchunks.push(decipher.update(cipherchunks[i], cipherencoding, clearencoding));
    }
    plainchunks.push(decipher.final(clearencoding));
    console.log(utf8 plaintext deciphered: + plainchunks.join(''));
的确,没错~~加密解密成功。但是和java,c#中加密出来的不一样啊。神啊。我想,大家都在这里纠结着吧~~对不对。其实只要加个向量,就可以和一致了。网上搜索出来的资源太少。才让自己纠结那么久。好吧,正确代码是:
复制代码 代码如下:
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       plainchunks.push(decipher.update(cipherchunks[i], cipherencoding, clearencoding));
    }
    plainchunks.push(decipher.final(clearencoding));
    console.log(utf8 plaintext deciphered: + plainchunks.join(''));
对比发现,加密出来是一致的。好吧,结贴~~~我恨你,浪费了我一天时间。
例子二:
工作中遇到nodejs端通过aes加密,安卓客户端java解密,同意nodejs也需要解密安卓客户端加密过来的内容,发现两个加密结果不一样,查询资料发现java端需要对密钥za再md5加密一遍,以下是aes ecb加密的内容,如果是cbc也同样需要对秘钥md5加密:
nodejs:
复制代码 代码如下:
/**
 * aes加密
 * @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解密
 * @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加密,与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); 
    }
/**
     * 字符串转字节数组
     * @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             result[i] = integer.valueof(hexstring.substring(2 * i, 2 * i + 2), 16).bytevalue(); 
        } 
        return result; 
    }
/**
     * 字节转16进制数组
     * @author lmiky
     * @date 2014-2-25
     * @param buf
     * @return
     */ 
    private static string parsebyte2hexstr(byte buf[]) { 
        stringbuffer sb = new stringbuffer(); 
        for (int i = 0; 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)); 
    } 
}
其它类似信息

推荐信息