node.js 实现 AES CTR 加解密

node aesctr

前言

由于最近我们在做一款安全的文件分享 App, 所有文件均需要使用 aes ctr 来进行加密,aes key 还有一整套完整的许可体系在保护, 然后再通知各种阅读器进行打开。

关于 aes ctr 不在此做说明,如需了解,请访问 : AES CTR 详细介绍

正文

直接上代码

'use strict'

var crypto = require('crypto')

// 异或 key 的加解算法
let alg = 'aes-256-ecb';
// 加密的数据块大小,单位字节
let block_size = 16; class AES {
/**
* 构造函数
* @param key_buffer aes key 的 byte 数组
* @param iv_buffer 随机数据的 byte 数组
*/
constructor(key_buffer,iv_buffer ){
this._key = key_buffer;
this._iv = iv_buffer;
} /**
* 加密
* @param data_buffer 明文数据
* @param offset 偏移量
* @returns {Buffer} 加密后的数据
*/
encryt(data_buffer, offset ){
return this._crypt(data_buffer, offset)
} /**
* 解密
* @param enc_data_buffer 加密后的数据
* @param offset 偏移量
* @returns {Buffer} 解密后的数据
*/
decrypt(enc_data_buffer, offset){
return this._crypt(enc_data_buffer, offset);
} /**
* 加解密传的数据块
* @param data_buffer 数据 buffer
* @param offset 偏移量,用于计算 counter
* @returns {Buffer} 加密或解密后的数据
* @private
*/
_crypt(data_buffer, offset){ let byte_length = data_buffer.length;
let enc_data_buffer = Buffer.alloc(byte_length); let start_counter = Math.floor(offset / block_size);
let total_counter = (offset+byte_length) % block_size == 0 ?
((offset+byte_length) / block_size)-1 :
Math.floor((offset+byte_length) / block_size);
// 已处理的字节长度
var handled_length = 0;
for(var i = start_counter; i<= total_counter; i++){
// 本次处理的字节长度
let handle_length = (i+1)*block_size-offset-handled_length;
if(handled_length + handle_length > byte_length){
handle_length = byte_length - handled_length;
}
let handle_data_buffer = data_buffer.slice(handled_length, handled_length + handle_length);
let handled_data_buffer = null;
if(i == 0 && handle_length < block_size && total_counter > 0){
handled_data_buffer = this._cryptBlock(handle_data_buffer, i, handle_length,-1);
} else {
handled_data_buffer = this._cryptBlock(handle_data_buffer, i, handle_length,0);
} enc_data_buffer.fill(handled_data_buffer,handled_length, handled_length+handle_length);
handled_length += handle_length; } return enc_data_buffer;
} /**
* 对16个字节的数据块的加解密
* @param data_buffer 要加密的16字节数据块
* @param counter 分块代号,从0开始
* @param length data_buffer 的长度,<=16, 多数情况下为 16,只有在不满 16 字节时才会 < 16
* @param forward -1: 表示数据块头不足 16 字节,0 表示正好是 16 字节 或 数据块尾不满 16 节节
* @returns {Buffer}
* @private
*/
_cryptBlock(data_buffer, counter, length, forward){ var xor_buffer = Buffer.alloc(block_size);
xor_buffer.fill(this._iv.slice(0,8),0,8)
xor_buffer.writeUIntBE(counter,10,6); let cipher = crypto.createCipheriv(alg,this._key,null);
var xor_key_buffer = cipher.update(xor_buffer);
cipher.final(); var enc_buffer = Buffer.alloc(length);
if(forward === -1){
let length_diff = block_size - length;
for(var i=length_diff;i<block_size;i++){
let number = data_buffer[i-length_diff] ^ xor_key_buffer[i];
enc_buffer[i-length_diff] = number;
}
} else {
for(var i =0; i < length; i++){
let number = data_buffer[i] ^ xor_key_buffer[i];
enc_buffer[i] = number;
}
}
return enc_buffer;
}
} exports.AES = AES;

 

node.js 实现 AES CTR 加解密的更多相关文章

  1. AES CBC/CTR 加解密原理

    So, lets look at how CBC works first. The following picture shows the encryption when using CBC (in ...

  2. AES对称加解密

    简介设计思想加密模式ECB模式(电子密码本模式:Electronic codebook)CBC模式(密码分组链接:Cipher-block chaining)CFB模式(密文反馈:Cipher fee ...

  3. 如何用node.js批量给图片加水印

    上一篇我们讲了如何用node.js给图片加水印,但是只是给某一张图片加,并没有涉及到批量处理.这一篇,我们学习如果批量进行图片加水印处理. 一.准备工作: 首先,你要阅读完这篇文章:http://ww ...

  4. java C# objective-c AES对称加解密

    /** * AES加解密 */ public class AESHelper { final static String AES_KEY = "43hr8fhu34b58123"; ...

  5. AES && DES加解密

    MD5加密一般不可逆,只能暴力突破.所以这边记录一下一些关于字符串的加解密的两种方法,以便自己学习 AES public class AESHelper { public static string ...

  6. JAVA AES文件加解密

    AES加解密算法,代码如下: /** * Created by hua on 2017/6/30. */ import javax.crypto.Cipher; import javax.crypto ...

  7. 最新版-Python和Java实现Aes相互加解密

    前情 需要使用Python和Java实现同一个AES加解密算法,使Python版本加密的密文能够由Java代码解密,反之亦然. Python实现 Python为3.6版本 # -*- coding: ...

  8. java,php,js;AES 互通加解密

      1,Java端(依赖 common-codec jar) package com.jiaMi; import javax.crypto.Cipher; import javax.crypto.sp ...

  9. Python AES - base64 加解密

    首先python引用AES加密 from Crypto.Cipher import AES 需要先安装  Crypto  模块, 可以使用 easy_install 进行安装   会自动去官网进行搜索 ...

随机推荐

  1. IDEA使用git提交代码时,点了commit之后卡死在performing code analysis部分,或者performing code analysis结束后没有进入下一步操作

    把"Perform code analysis" 和 "Check TODO" 复选框前面的勾去掉就好了. 这个可能是因为所分析的目标文件太大了,造成一直分析不 ...

  2. Day02:正则表达式 / Object / 包装类

    JAVA正则表达式 实际开发中,经常需要对字符串数据进行一些复杂的匹配,查找,替换等操作. 通过"正则表达式",可以方便的实现字符串的复杂操作. 正则表达式是一串特定字符,组成一个 ...

  3. P1141 01迷宫(连通块模板)

    题目描述 有一个仅由数字0与1组成的n×n格迷宫.若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上. 你的任务是:对于给定的迷宫, ...

  4. shell脚本判断里面的字符含义

    [ -s FILE ] 如果 FILE 存在且大小不为0则为真. [ -a FILE ] 如果 FILE 存在则为真. [ -b FILE ] 如果 FILE 存在且是一个块特殊文件则为真. [ -c ...

  5. es5实现数组去重

    var a = [1, 2, 4, 4, 3, 3, 1, 5, 3] console.log(a.filter((item, index, arr) => { return arr.index ...

  6. Spring Boot(十七):使用 Spring Boot 上传文件

      上传文件是互联网中常常应用的场景之一,最典型的情况就是上传头像等,今天就带着带着大家做一个 Spring Boot 上传文件的小案例. 1.pom 包配置 我们使用 Spring Boot 版本 ...

  7. Linux系统基础知识整理(一)

    本文来自于: https://www.cnblogs.com/hafiz/p/6686187.html#4196989 一.说明 本篇文章,我将结合自己的实践以及简介,来对linux系统做一个直观清晰 ...

  8. ubuntu 安装 Gurobi 的tips

    要跑的一个深度学习框架用到了gurobi 安装在ubuntu上栽了两天时间,我安装的是ubuntu16.04的版本 自己去官网下载gurobi,我安装的是gurobi8.1.1 然后申请相应的lice ...

  9. filebeat开启自带模块收集日志如何辨别日志来源等

    filebeat启动自带模块后,日志先输出到Redis中 比如开启了system模块日志和redis模块日志 在Redis中查看收集过来的日志时,可以看到如下的这些信息 system日志信息 { &q ...

  10. C++ new、delete、namespace关键字。

    C++ 中的动态内存分配: C++与C语言分配内存关键字不同,C语言中的动态内存分配是通过 malloc(分配内存) 与 free(释放内存)完成.C++使用new(分配内存)  delete(释放内 ...