Node.js的crypto模块提供了一组包括对OpenSSL的哈希、HMAC、加密、解密、签名,以及验证等一整套功能的封装。具体的使用方法可以参考这篇文章中的描述:node.js_crypto模块

  本文重点介绍在使用createCipheriv方法时所遇到的坑。对应的解密算法createDecipheriv应该是一样的问题。

  按照文档中的描述,createCipheriv方法接受三个参数:algorithm用于指定加密算法,如aes-128-ecb、aes-128-cbc等;key是用于加密的密钥;iv参数可选,用于指定加密时所用的向量。注意这里的密钥必须是8/16/32位,如果加密算法是128,则对应的密钥是16位,如果加密算法是256,则对应的密钥是32位。代码如下:

const crypto = require("crypto");

function encrypt (key, iv, data) {
let decipher = crypto.createCipheriv('aes-128-cbc', key, iv);
// decipher.setAutoPadding(true);
return decipher.update(data, 'binary', 'base64') + decipher.final('base64');
} function decrypt (key, iv, crypted) {
crypted = new Buffer(crypted, 'base64').toString('binary');
let decipher = crypto.createDecipheriv('aes-128-cbc', key, iv);
return decipher.update(crypted, 'binary', 'utf8') + decipher.final('utf8');
}

  下面是测试结果:

let key = '123456789abcdefg';
console.log('加密的key:', key);
let iv = 'abcdefg123456789';
console.log('加密的iv:', iv);
let data = "This is an example";
console.log("需要加密的数据:", data);
let crypted = encrypt(key, iv, data);
console.log("数据加密后:", crypted);
let dec = decrypt(key, iv, crypted);
console.log("数据解密后:", dec);

  以上加密和解密的算法在node.js中运行没有问题。但如果服务端用的不是node.js,而是Java、C#或者C语言编写的服务,则用node.js加密之后的结果在服务端验证无法通过。究其原因可能是因为node.js在实现createCipheriv的算法上与其它语言有差异,而这个差异也可能体现在编码格式上。在上述node.js代码中,无论如何修改encrypt函数中update()和final()方法的参数,例如改为"utf8"、"hex",或者将传入的参数改为buffer等,虽然得出的加密结果会有区别,但是服务端验证都会失败。

  在多次尝试失败后,我们只能认定node.js中的crypto模块与其它语言中的实现存在差异。所以我们不得已选择其它的开源包来替换node.js中的crypto模块。经过尝试,aes-js包是个不错的选择。按照文档中的描述,我们将上面node.js中的encrypt函数修改为:

const aesjs = require('aes-js');

function encrypt (key, iv, data) {
let aesCbc = new aesjs.ModeOfOperation.cbc(aesjs.utils.utf8.toBytes(key), aesjs.utils.utf8.toBytes(iv));
let encryptedBytes = aesCbc.encrypt(aesjs.utils.utf8.toBytes(data));
return aesjs.utils.hex.fromBytes(encryptedBytes);
} function decrypt (key, iv, crypted) {
let aesCbc = new aesjs.ModeOfOperation.cbc(aesjs.utils.utf8.toBytes(key), aesjs.utils.utf8.toBytes(iv));
let encryptedBytes = aesCbc.decrypt(aesjs.utils.hex.toBytes(crypted));
return aesjs.utils.utf8.fromBytes(encryptedBytes);
}

  上面这段代码要求加密的数据是16位,测试结果如下:

let key = '123456789abcdefg';
console.log('加密的key:', key);
let iv = 'abcdefg123456789';
console.log('加密的iv:', iv);
let data = "Thisisanexample.";
console.log("需要加密的数据:", data);
let crypted = encrypt(key, iv, data);
console.log("数据加密后:", crypted);
let dec = decrypt(key, iv, crypted);
console.log("数据解密后:", dec);

  采用aes-js计算得到的加密结果可以通过服务端的验证。

记一次在node.js中使用crypto的createCipheriv方法进行加密时所遇到的坑的更多相关文章

  1. node.js中的http.response.end方法使用说明

    转载自:http://m.jb51.net/article/58468.htm 本文介绍了http.response.end的方法说明.语法.接收参数.使用实例和实现源码,需要的朋友可以参考下 方法说 ...

  2. 在node.js中,使用基于ORM架构的Sequelize,操作mysql数据库之增删改查

    Sequelize是一个基于promise的关系型数据库ORM框架,这个库完全采用JavaScript开发并且能够用在Node.JS环境中,易于使用,支持多SQL方言(dialect),.它当前支持M ...

  3. 如何在Node.js中合并两个复杂对象

    通常情况下,在Node.js中我们可以通过underscore的extend或者lodash的merge来合并两个对象,但是对于像下面这种复杂的对象,要如何来应对呢? 例如我有以下两个object: ...

  4. Node.js中的Session,不要觉得简单哦。

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,博客地址为http://www.cnblogs.com/jasonnode/ .学习网站上有对应 ...

  5. Node.js 中MongoDB的基本接口操作

    Node.js 中MongoDB的基本接口操作 连接数据库 安装mongodb模块 导入mongodb模块 调用connect方法 文档的增删改查操作 插入文档 方法: db.collection(& ...

  6. 在node.js中使用COOKIE

    node.js中如何向客户端发送COOKIE呢?有如下两个方案: 一.使用response.writeHead,代码示例: //设置过期时间为一分钟 var today = new Date(); v ...

  7. 初步揭秘node.js中的事件

    当你学习node.js的时候,Events是一个非常重要的需要理解的事情.非常多的Node对象触发事件,你能在文档API中找到很多例子.但是关于如何写自己的事件和监听,你可能还不太清楚.如果你不了解, ...

  8. Node.js权威指南 (10) - Node.js中的错误处理与断言处理

    10.1 使用domain模块处理错误 / 272 10.1.1 domain模块概述 / 272 10.1.2 创建并使用Domain对象 / 274 10.1.3 隐式绑定与显式绑定 / 276 ...

  9. Node.js中的URL

    Node.js中的URL 什么是URL URL是Uniform Location Resource的缩写,翻译为"统一资源定位符",也就是描述资源位置的固定表示方法.被URL描述的 ...

随机推荐

  1. 给一线讲产品·8期|VPC、子网、安全组,是什么关系?

    欢迎添加华为云小助手微信(微信号:HWCloud002 或 HWCloud003),输入关键字"加群",加入华为云线上技术讨论群:输入关键字"最新活动",获取华 ...

  2. mysql数据库命令

    删除一个表: drop table if exists 表名; 在表中插入行: Insert into 表名 values(, , ,) 创建表: Create table 表名( Id int(10 ...

  3. oracle监听查看、启动和停止

    oracle监听查看.启动和停止 查看监听lsnrctl status 停止监听lsnrctl stop 启动监听lsnrctl start

  4. 智能家居CC2530功率放大组网RFX2401C和AT2401C的区别

    两者最大的区别就是RFX2401C的增益为12dbmAT2401C的增益为14dbm这就会导致AT2401C的功耗会比RFX2401C大一点点,但距离也会相对更远,并且增加了EDS防静电等级,多出2个 ...

  5. git 使用详解(4)—— commit -a -m/diff --staged/rm/mv

    查看已暂存和未暂存的更新 实际上 git status的显示比较简单,仅仅是 列出了(修改过的.新创建的.已经暂存但未提交的)文件,如果要查看具体修改了什么地方,可以用git diff 命令.稍后我们 ...

  6. 【解决】image ... could not be accessed on a registry to record its digest.

    [问题]image jmdiservice:1206 could not be accessed on a registry to record its digest. Each node will ...

  7. CodeForces1000A- Codehorses T-shirts

    A. Codehorses T-shirts time limit per test 2 seconds memory limit per test 256 megabytes input stand ...

  8. Python基础第二课

    字符串(引号):四种表达方式 n1 = "我是" n1 = '我是' n1 = """我是""" n1 = '" ...

  9. Python文件头注释的含义,你肯定不懂

    前言本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:冰火梦幻  本文档描述了Python语言文件头里典型注释的含义. 1. ...

  10. 上手spring boot项目(三)之spring boot整合mybatis进行增删改查

    使用mybatis框架进行增删改查大致有两种基础方式,一种扩展方式.两种基础方式分别是使用xml映射文件和使用方法注解.扩展方式是使用mybatis-plus的方式,其用法类似于spring-data ...