node.js 实现 AES CTR 加解密

node aesctr

前言

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

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

正文

直接上代码

  1. 'use strict'
  2.  
  3. var crypto = require('crypto')
  4.  
  5. // 异或 key 的加解算法
  6. let alg = 'aes-256-ecb';
  7. // 加密的数据块大小,单位字节
  8. let block_size = 16;
  9.  
  10. class AES {
  11. /**
  12. * 构造函数
  13. * @param key_buffer aes key 的 byte 数组
  14. * @param iv_buffer 随机数据的 byte 数组
  15. */
  16. constructor(key_buffer,iv_buffer ){
  17. this._key = key_buffer;
  18. this._iv = iv_buffer;
  19. }
  20.  
  21. /**
  22. * 加密
  23. * @param data_buffer 明文数据
  24. * @param offset 偏移量
  25. * @returns {Buffer} 加密后的数据
  26. */
  27. encryt(data_buffer, offset ){
  28. return this._crypt(data_buffer, offset)
  29. }
  30.  
  31. /**
  32. * 解密
  33. * @param enc_data_buffer 加密后的数据
  34. * @param offset 偏移量
  35. * @returns {Buffer} 解密后的数据
  36. */
  37. decrypt(enc_data_buffer, offset){
  38. return this._crypt(enc_data_buffer, offset);
  39. }
  40.  
  41. /**
  42. * 加解密传的数据块
  43. * @param data_buffer 数据 buffer
  44. * @param offset 偏移量,用于计算 counter
  45. * @returns {Buffer} 加密或解密后的数据
  46. * @private
  47. */
  48. _crypt(data_buffer, offset){
  49.  
  50. let byte_length = data_buffer.length;
  51. let enc_data_buffer = Buffer.alloc(byte_length);
  52.  
  53. let start_counter = Math.floor(offset / block_size);
  54. let total_counter = (offset+byte_length) % block_size == 0 ?
  55. ((offset+byte_length) / block_size)-1 :
  56. Math.floor((offset+byte_length) / block_size);
  57. // 已处理的字节长度
  58. var handled_length = 0;
  59. for(var i = start_counter; i<= total_counter; i++){
  60. // 本次处理的字节长度
  61. let handle_length = (i+1)*block_size-offset-handled_length;
  62. if(handled_length + handle_length > byte_length){
  63. handle_length = byte_length - handled_length;
  64. }
  65. let handle_data_buffer = data_buffer.slice(handled_length, handled_length + handle_length);
  66. let handled_data_buffer = null;
  67. if(i == 0 && handle_length < block_size && total_counter > 0){
  68. handled_data_buffer = this._cryptBlock(handle_data_buffer, i, handle_length,-1);
  69. } else {
  70. handled_data_buffer = this._cryptBlock(handle_data_buffer, i, handle_length,0);
  71. }
  72.  
  73. enc_data_buffer.fill(handled_data_buffer,handled_length, handled_length+handle_length);
  74. handled_length += handle_length;
  75.  
  76. }
  77.  
  78. return enc_data_buffer;
  79. }
  80.  
  81. /**
  82. * 对16个字节的数据块的加解密
  83. * @param data_buffer 要加密的16字节数据块
  84. * @param counter 分块代号,从0开始
  85. * @param length data_buffer 的长度,<=16, 多数情况下为 16,只有在不满 16 字节时才会 < 16
  86. * @param forward -1: 表示数据块头不足 16 字节,0 表示正好是 16 字节 或 数据块尾不满 16 节节
  87. * @returns {Buffer}
  88. * @private
  89. */
  90. _cryptBlock(data_buffer, counter, length, forward){
  91.  
  92. var xor_buffer = Buffer.alloc(block_size);
  93. xor_buffer.fill(this._iv.slice(0,8),0,8)
  94. xor_buffer.writeUIntBE(counter,10,6);
  95.  
  96. let cipher = crypto.createCipheriv(alg,this._key,null);
  97. var xor_key_buffer = cipher.update(xor_buffer);
  98. cipher.final();
  99.  
  100. var enc_buffer = Buffer.alloc(length);
  101. if(forward === -1){
  102. let length_diff = block_size - length;
  103. for(var i=length_diff;i<block_size;i++){
  104. let number = data_buffer[i-length_diff] ^ xor_key_buffer[i];
  105. enc_buffer[i-length_diff] = number;
  106. }
  107. } else {
  108. for(var i =0; i < length; i++){
  109. let number = data_buffer[i] ^ xor_key_buffer[i];
  110. enc_buffer[i] = number;
  111. }
  112. }
  113. return enc_buffer;
  114. }
  115. }
  116.  
  117. 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. ControlTemplate in WPF —— Expander

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" x ...

  2. Centos 7 安装tomcat并部署jar实录

    本文目的 纯属记录,以备后查. 1.安装JAVA JDK 安装jdk略. 配置JDK,打开/etc/profile文件,在最后添加如下代码: JAVA_HOME=/usr/java/jdk1..0_2 ...

  3. Nova 启动虚拟机流程解析

    目录 文章目录 目录 前言 从请求说起 nova-api service 阶段 前言 Nova 启动虚拟机的东西太多,持续更新- 从请求说起 无论是通过 Dashboard 还是 CLI 启动一个虚拟 ...

  4. 2 Configuring SAP ERP Sales and Distribution -introduction to SAP

    First Steps in SAPWe’ll now discuss some of the basic menus, screens, and transactions that you need ...

  5. 【Java学习笔记】LinkedList JDK1.6

    如下一段代码,在JDK1.6的LinkedList中,是下图这样存储的.有一个节点值为null的节点,叫做header,header的next是0,3的next是header,这是一个循环链表 Lin ...

  6. Could not find aapt Please set the ANDROID_HOME environment variable with the Android SDK root directory path

    写case写好好哒,突然debug的时候就冒出这个错误: selenium.common.exceptions.WebDriverException: Message: An unknown serv ...

  7. oop理论

    三大特性: 封装:把对象的属性和行为独立的一个整体,并尽可能的隐藏对象内部实现细节.增加安全性. 继承:从已有的类中派生出新的类,称为子类,子类继承父类的属性和行为,并能根据自己的需求扩展出新的行为. ...

  8. php连接mysql,数据CRUD操作

    插入数据 <?php $name = $_GET['username']; $sex = $_GET['sex']; $hobby = $_GET['hobby']; $address = $_ ...

  9. 如何解决idea本身的乱码以及解决代码中出现的乱码?

    1:解决idea中控制台的乱码现象(3中方法): 第一种: 如图需要找到idea的安装路径: idea\IntelliJ IDEA 2018.3.2\bin 在这个路径下面有一个文件叫:idea64. ...

  10. 详解MySql的配置文件my.cnf

    1.Windows下MySQL的配置文件是my.ini,一般会在安装目录的根目录. 2.Linux下MySQL的配置文件是my.cnf,一般会放在/etc/my.cnf,/etc/mysql/my.c ...