Node 实现 AES 加密,结果输出为“byte”。

最近做个需求,对接一个平台的接口,该平台采用 AES (Advanced Encryption Standard)加密算法,加密模式为 AES-128-CBC,补码方式为 AES/CBC/PKCS5Padding,密钥和向

量均为 16 位。加密结果为 Byte 数组

用 Node 比较不好的一个地方就是,第三方接口一般都不会有 Node 的实现,所以只能自己写了。

Node 中已经提供了加密的的库 crypto ,查看官方文档 https://nodejs.org/api/crypto.html,可以找到实现这次加密需要的东西

crypto.createCipheriv(algorithm, key, iv)

该方法会创建一个 crypto 对象,用来加密信息。

参数 key 和 iv 是密匙和向量。

参数 algorithm 是指加密算法,也就是 OpenSSL 支持的所有 cipher 加密算法,使用以下命令列出所有算法。

 openssl list-cipher-algorithms

当然了,我们这次使用的 AES-128-CBC 加密算法肯定是支持的。废话不多说,直接上代码:

/**
*
* @param data 加密的数据
* @param key 密匙
* @param algorithm 算法
* @param clearEncoding 明文的编码格式
* @param cipherEncoding 密文的编码格式
* @param iv 向量
* @returns {*}buffer 数组
*/
function encrypt(data, key, iv, algorithm) {
// 创建crypto 对象
var cipher = crypto.createCipheriv(algorithm, key, iv);
// 使用自动补码 关于补码的解释文档中也有说明
cipher.setAutoPadding(true);
var cipherChunks = [];
// 加密数据 update 方法可以执行多次。
var upate = cipher.update(new Buffer(data));
cipherChunks.push(upate);
// 结束加密
cipherChunks.push(cipher.final());
return bufferToByte(cipherChunks);
}
var encryptData = encrypt('要被加密的字符串', key, iv, 'AES-128-CBC');
console.log('加密结果 :', encryptData);

这里有个地方需要注意 update + final 的结果才是最终结果,只取 final 的结果是不够的。

查看文档可以知道cipher 默认的输出格式是 Buffer ,Node 中的 Buffer 就是二进制串,关于Buffer的详细可以看看这篇文章 深入浅出Node.js(六):Buffer那些事儿

需求中要求是输出 byte 数组,但是 Node 中并没有 byte 类型,这是 Java 中才有的,其值范围是 -127~127 。既然没有,那就自己写Buffer to byte 函数 bufferToByte 吧。

/**
* 将 buffer 数组转换为 byte
* @param buffers
* @returns {string}
*/
function bufferToByte(buffers) {
var rt = [];
for (var i = 0; i < buffers.length; i++) {
var buffer = buffers[i];
for (var j = 0; j < buffer.length; j++) {
var c = buffer.readInt8(j);
rt.push(c);
}
}
//console.log('rt', rt);
return rt.join(' ');
}

这个方法主要用到了 Buffer 提供的 readInt8 函数,意思是每次从 buffer 中读 8位二进制数,2^8 刚好是 -127 ~ 127 也就是我们要的 “byte”。

最后输出结果:

加密结果 : -18 22 105 -22 84 -106 29 -24 -23 -91 -92 -37 20 48 58 51 -34 -65 27 -106 -13 109 25 66 55 -3 -7 4 -25 113 97 6

总结:

  1. cipher 加密的完整结果是 update + final 的结果。
  2. Buffer 提供了读取二进制数的方法, readInt8 只是其中一个,详细见官方文档:https://nodejs.org/api/buffer.html#buffer_class_buffer
  3. 关于补码,这次使用了默认的 setAutoPadding 就满足了需求,如果你需要特殊的补码方式,文档里都有写~

参考:http://yijiebuyi.com/blog/13e2ae33082ac12ba4946b033be04bb5.html

Node 实现 AES 加密,结果输出为“byte”。的更多相关文章

  1. C#, Java, PHP, Python和Javascript几种语言的AES加密解密实现[转载]

    原文:http://outofmemory.cn/code-snippet/35524/AES-with-javascript-java-csharp-python-or-php c#里面的AES加密 ...

  2. Aes加密/解密示例项目

    #AesEncrypt:Aes加密/解密示例项目 <br> 附件中的“AesEncrypt.zip”是本项目的exe文件,可直接下载下来运行和查看. *高级加密标准(英语:Advanced ...

  3. C#, Java, PHP, Python和Javascript几种语言的AES加密解密实现

    特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...

  4. asp.net AES加密跟PHP的一致,将加密的2进制byte[]转换为16进制byte[] 的字符串获得

    <?php class AESUtil { public static function encrypt($input, $key) { $size = mcrypt_get_block_siz ...

  5. 参考别人的代码写的aes加密,记录一下(AES,ECB模式,填充PKCS5Padding,数据块128位,偏移量无,以hex16进制输出)

    package org.jimmy.autosearch2019.test; import java.security.SecureRandom; import javax.crypto.Cipher ...

  6. Java aes加密C#解密的取巧方法

    摘要: 项目开发过程中遇到一个棘手的问题:A系统使用java开发,通过AES加密数据,B系统使用C#开发,需要从A系统获取数据,但在AES解密的时候遇到麻烦.Java的代码和C#的代码无法互通. Ja ...

  7. Java 环境下使用 AES 加密的特殊问题处理

    在 Java 环境下使用 AES 加密,在密钥长度和字节填充方面有一些比较特殊的处理. 1. 密钥长度问题 默认 Java 中仅支持 128 位密钥,当使用 256 位密钥的时候,会报告密钥长度错误 ...

  8. openssl与cryptoAPI交互AES加密解密

    继上次只有CryptoAPI的加密后,这次要实现openssl的了 动机:利用CryptoAPI制作windows的IE,火狐和chrome加密控件后,这次得加上与android的加密信息交互 先前有 ...

  9. DES加密解密与AES加密解密

    随着开发时间的变长,当初认为比较难的东西,现在渐渐也就变的不那么难了!特别对于一些经常很少使用的类,时间长了之后渐渐就陌生了.所以在这里写一些日后可能会用到的加密与解密. 一.AES加密算法和DES加 ...

随机推荐

  1. RobotFramework-调用.py文件

    RobotFramework-调用.py文件,直接运行: 注意:文件路径的\全部换成好了/

  2. 【Ubuntu】NAT配置

    1.简介 2.配置 1.简介 NAT(Network Address Translation,网络地址转换)是将IP 数据包头中的IP 地址转换为另一个IP 地址的过程.在实际应用中,NAT 主要用于 ...

  3. 【BZOJ】【1046】【HAOI2007】上升序列

    DP+贪心 啊……其实是个水题,想的复杂了 令f[i]表示以 i 为起始位置的最长上升子序列的长度,那么对于一个询问x,我们可以贪心地从前往后扫,如果f[i]>=x && a[i ...

  4. NYOJ-205 求余数 AC 分类: NYOJ 2014-02-02 12:30 201人阅读 评论(0) 收藏

    这题目看一眼以为难度评级出错了,只是一个求余数的题目,,后来才发现,位数小于百万位,,,我还以为是大小小于百万呢,所以借鉴了另一大神的代码, 用大数,重点是同余定理: (a+b)mod m=((a m ...

  5. ubuntu 安装完成后的工作

    以安装 ubuntu 15.10 为例 1. 备份并更改源 cd /etc/apt sudo cp source.list source.list.bak sudo vi source.list 删除 ...

  6. unity3d中dllimport方法的使用,以接入腾讯平台为例!!!

    说到有关dllimport方法可能还有很多人比较陌生,其实我自己也说不太清楚,大概说说什么时候要用它. 事实上功能类似于调用android的第三包,我们想要使用苹果上特定的api或者第三方平台的一些东 ...

  7. Linux系统下利用wget命令把整站下载做镜像网站

    Linux系统下利用wget命令把整站下载做镜像网站 2011-05-28 18:13:01 | 1次阅读 | 评论:0 条 | itokit  在linux下完整的用wget命令整站采集网站做镜像 ...

  8. WCF Service的Restfull风格

    怎样构建? •您需要什么样的资源? •将使用哪些 URI 表示这些资源? •每个 URI 将支持统一接口的哪些部件(HTTP 动词)?    URI的处理   •UriTemplate –System ...

  9. codeforces 455B A Lot of Games(博弈,字典树)

    题目 参考自博客:http://blog.csdn.net/keshuai19940722/article/details/38455269 //字典树,博弈 根据当前节点的后续来确定当前节点的状态, ...

  10. awk处理之案例四:sort加awk来过滤文本

    编译环境 本系列文章所提供的算法均在以下环境下编译通过. [脚本编译环境]Federa 8,linux 2.6.35.6-45.fc14.i686 [处理器] Intel(R) Core(TM)2 Q ...