`

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

阅读更多

例子一:

这几天被一个问题困扰着。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 < cipherChunks.length;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 < cipherChunks.length;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 < len; 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 < 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"));  
    }  
}

 

分享到:
评论

相关推荐

    4.nodejs和java的AES加密结果保持一致.doc

    在 Node.js 和 Java 中实现 AES 加密结果保持一致是非常重要的。以下是相关知识点的详细解释: AES 加密简介 AES(Advanced Encryption Standard)是一种对称加密算法,主要用于保护数据的机密性和完整性。AES ...

    Java与Node.js利用AES加密解密出相同结果的方法示例

    1. **密钥处理**:由于Java和Node.js中加密结果不一致的问题,Java端对密钥进行了MD5哈希处理。代码中`MessageDigest.getInstance("MD5")`用于生成密钥的MD5摘要,然后使用这个摘要创建`SecretKeySpec`对象。 2. **...

    nodejs的base64和aes-128-ecb加密.rar

    在这个"nodejs的base64和aes-128-ecb加密.rar"压缩包中,包含的`EncryptTool.js`和`EncryptTool.ts`文件很可能是两个实现Base64编码和AES-128-ECB加密的工具类。接下来,我们将深入探讨这两个知识点。 首先,Base64...

    如何在Node.js中加密和解密数据.pdf

    ### 如何在Node.js中加密和解密数据 #### 一、引言 随着网络通信的日益普及,数据安全成为了开发者不可忽视的重要议题之一。在众多保护数据安全的方法中,加密技术是其中不可或缺的一部分。Node.js 作为一种广泛...

    AES加密算法详解及Python与Node.js实现案例

    同时,文中还提供使用Python(PyCryptodome库)和Node.js(crypto模块)两种流行的编程语言实现实例,并指出在实际运用过程中的一些注意事项,诸如密钥管理和加密模式的选择等。 适合人群:对密码学感兴趣的技术...

    node.js的加密模块.zip

    在Node.js环境中,加密(crypto)模块是内置的核心模块之一,它提供了各种加密和散列功能,用于数据安全。这个“node.js的加密模块.zip”很可能包含了一个名为“node-crypto-master”的项目,该项目可能是对Node.js...

    node.js接入支付宝加签

    1. **Node.js基础**:Node.js是一个基于Chrome V8引擎的JavaScript运行环境,它允许开发者在服务器端使用JavaScript进行编程,具有高效、非阻塞I/O和模块化等优点。 2. **支付宝接口**:支付宝提供了丰富的API接口...

    Node.js中密码学的7个有用示例.zip

    在Node.js中,可以通过`crypto.createCipheriv()`创建一个对称加密流,然后使用`update()`和`final()`方法处理数据。 3. **非对称加密**: 非对称加密如RSA,使用一对公钥和私钥,公钥用于加密,私钥用于解密。在...

    AES加密解密算法C# JAVA nodejs通用

    C# JAVA nodejs通用的AES加密解密算法,考虑到实际使用过程中由于客户端和服务端使用的语言不一样而又需要对数据进行加密和解密的情况,特此总结了C# JAVA nodejs通用的AES加密解密算法,供需要者参考。

    常用的js加密库。MD5,AES,DES等

    JavaScript(简称JS)作为一种广泛应用于前端开发的编程语言,经常需要处理数据安全问题,尤其是在传输敏感信息时。本文将深入探讨在JS中常用的加密库,包括MD5、AES和DES,以及如何使用CryptoJS这个加密库来实现...

    node.js的W3CXML加密实现(httpwww.w3.orgTRxmlenc-core).zip

    标题中的“node.js的W3CXML加密实现”指的是在Node.js环境中,使用XML加密标准(W3C XML Encryption)来对数据进行安全保护的一种技术。XML加密是W3C组织发布的一种规范,用于XML文档的安全传输和存储,它允许XML...

    加密解密AES crypto的js封装代码

    如果你的项目中同时有Node.js后端和JavaScript前端,可以确保双方使用相同的加密库和方式,以保证数据的一致性。在Node.js中,可以使用`crypto`模块,但需要自行处理密钥和初始化向量的转换。 7. **扩展** `...

    用于Node.js的W3CWeb加密API.zip

    **Node.js中的W3C Web加密API** W3C Web加密API(Web Cryptography API)是一种标准化的JavaScript API,允许Web应用在用户浏览器中执行加密、解密、签名和验证等安全操作。这个API旨在为Web开发人员提供一套强大且...

    cabal-node-基于p2p功能用于聊天的Node.js库

    9. **事件驱动编程**:Node.js中的事件驱动模型,如何监听和处理事件。 10. **错误处理与调试**:在分布式系统中,如何处理异常并进行有效的调试。 以上是基于“cabal-node”库的相关知识点,涵盖了从基础的Node.js...

    hybrid-crypto-js:针对JavaScript的RSA + AES混合加密实现。 与Node.js,React Native和现代浏览器一起使用

    Hybrid Crypto JS结合了RSA和AES加密算法,可以有效地加密和解密大型邮件。 该跨平台库基于 。 Hybrid Crypto JS可以在浏览器,Node.js或React Native中使用。 文献资料 入门 产品特点 安装 npm install hybrid-...

    aes加密的JavaScript实现

    JavaScript中的AES加密和解密不仅应用于浏览器环境,还可以在Node.js环境中使用。理解这些概念并能正确实现AES加密是信息安全领域中的基本技能,对于保护用户数据和构建安全的网络应用至关重要。

Global site tag (gtag.js) - Google Analytics