aes-js中文文档|aes-js js中文教程|解析

npm npmdoc 2年前 (2021-12-09) 1832次浏览

aes-js中文文档|aes-js js中文教程|解析

安装命令:npm i aes-js

AES-JS

npm 版本

AES 分组密码算法和所有常见操作模式(CBC、CFB、CTR、ECB 和 OFB)的纯 JavaScript 实现。

特征

  • 纯 JavaScript(无依赖)
  • 支持所有密钥大小(128 位、192 位和 256 位)
  • 支持所有常见的操作模式(CBC、CFB、CTR、ECB 和 OFB)
  • 适用于 node.js 或 Web 浏览器

从 2.x 迁移到 3.x

实用程序函数已在 3.x 分支中重命名,因为它们在字节和字符串之间的转换引起了大量混淆。

这些示例也已更新为将二进制数据编码为可打印的十六进制字符串。

字符串和字节

字符串应该被用作键。UTF-8 允许可变长度的多字节字符,因此 16 个字符的字符串可能不是 16个字节长。

此外,UTF8应用于存储任意二进制数据,因为它是字符串编码格式,而不是二进制编码格式。

// aesjs.util.convertStringToBytes(aString)
// Becomes:
aesjs.utils.utf8.toBytes(aString)
 
 
// aesjs.util.convertBytesToString(aString)
// Becomes:
aesjs.utils.utf8.fromBytes(aString)

字节和十六进制字符串

二进制数据,如加密字节,可以安全地存储和打印为十六进制字符串。

// aesjs.util.convertStringToBytes(aString, 'hex')
// Becomes:
aesjs.utils.hex.toBytes(aString)
 
 
// aesjs.util.convertBytesToString(aString, 'hex')
// Becomes:
aesjs.utils.hex.fromBytes(aString)

类型化数组

3.x及以上版本的aes-js使用Uint8Array代替Array,与Browserify一起使用时减少了代码量(不再拉入Buffer),速度也提高了一倍左右

但是,如果您需要支持早于 IE 10 的浏览器,则应继续使用 2.x 版。

应用程序接口

节点.js

要安装aes-js在您的 node.js 项目中:

npm install aes-js

要从节点内访问它,只需添加:

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

网页浏览器

aes-js在网页中使用,请添加以下内容:

<script type="text/javascript" src="https://cdn.rawgit.com/ricmoo/aes-js/e27b99df/index.js"></script>

钥匙

所有密钥的长度必须为 128 位(16 字节)、192 位(24 字节)或 256 位(32 字节)。

该库使用Array,Uint8ArrayBuffer对象以及任何类似数组的对象(即必须具有length属性,并且每个条目都具有有效的字节值)。

// 128-bit, 192-bit and 256-bit keys
var key_128 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
var key_192 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
               16, 17, 18, 19, 20, 21, 22, 23];
var key_256 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
               16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
               29, 30, 31];
 
// or, you may use Uint8Array:
var key_128_array = new Uint8Array(key_128);
var key_192_array = new Uint8Array(key_192);
var key_256_array = new Uint8Array(key_256);
 
// or, you may use Buffer in node.js:
var key_128_buffer = Buffer.from(key_128);
var key_192_buffer = Buffer.from(key_192);
var key_256_buffer = Buffer.from(key_256);

要从易于记忆的密码生成密钥,请考虑使用基于密码的密钥派生函数,例如scryptbcrypt

常见的操作模式

有几种操作模式,每种模式都有不同的优点和缺点。但一般而言,建议使用CBCCTR模式。不建议欧洲央行。,并且主要是为了完整性而包括在内。

CTR – 计数器(推荐)

// An example 128-bit key (16 bytes * 8 bits/byte = 128 bits)
var key = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 ];
 
// Convert text to bytes
var text = 'Text may be any length you wish, no padding is required.';
var textBytes = aesjs.utils.utf8.toBytes(text);
 
// The counter is optional, and if omitted will begin at 1
var aesCtr = new aesjs.ModeOfOperation.ctr(key, new aesjs.Counter(5));
var encryptedBytes = aesCtr.encrypt(textBytes);
 
// To print or store the binary data, you may convert it to hex
var encryptedHex = aesjs.utils.hex.fromBytes(encryptedBytes);
console.log(encryptedHex);
// "a338eda3874ed884b6199150d36f49988c90f5c47fe7792b0cf8c7f77eeffd87
//  ea145b73e82aefcf2076f881c88879e4e25b1d7b24ba2788"
 
// When ready to decrypt the hex string, convert it back to bytes
var encryptedBytes = aesjs.utils.hex.toBytes(encryptedHex);
 
// The counter mode of operation maintains internal state, so to
// decrypt a new instance must be instantiated.
var aesCtr = new aesjs.ModeOfOperation.ctr(key, new aesjs.Counter(5));
var decryptedBytes = aesCtr.decrypt(encryptedBytes);
 
// Convert our bytes back into text
var decryptedText = aesjs.utils.utf8.fromBytes(decryptedBytes);
console.log(decryptedText);
// "Text may be any length you wish, no padding is required."

CBC – 密码块链(推荐)

// An example 128-bit key
var key = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 ];
 
// The initialization vector (must be 16 bytes)
var iv = [ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,35, 36 ];
 
// Convert text to bytes (text must be a multiple of 16 bytes)
var text = 'TextMustBe16Byte';
var textBytes = aesjs.utils.utf8.toBytes(text);
 
var aesCbc = new aesjs.ModeOfOperation.cbc(key, iv);
var encryptedBytes = aesCbc.encrypt(textBytes);
 
// To print or store the binary data, you may convert it to hex
var encryptedHex = aesjs.utils.hex.fromBytes(encryptedBytes);
console.log(encryptedHex);
// "104fb073f9a131f2cab49184bb864ca2"
 
// When ready to decrypt the hex string, convert it back to bytes
var encryptedBytes = aesjs.utils.hex.toBytes(encryptedHex);
 
// The cipher-block chaining mode of operation maintains internal
// state, so to decrypt a new instance must be instantiated.
var aesCbc = new aesjs.ModeOfOperation.cbc(key, iv);
var decryptedBytes = aesCbc.decrypt(encryptedBytes);
 
// Convert our bytes back into text
var decryptedText = aesjs.utils.utf8.fromBytes(decryptedBytes);
console.log(decryptedText);
// "TextMustBe16Byte"

CFB – 密码反馈

// An example 128-bit key
var key = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 ];
 
// The initialization vector (must be 16 bytes)
var iv = [ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,35, 36 ];
 
// Convert text to bytes (must be a multiple of the segment size you choose below)
var text = 'TextMustBeAMultipleOfSegmentSize';
var textBytes = aesjs.utils.utf8.toBytes(text);
 
// The segment size is optional, and defaults to 1
var segmentSize = 8;
var aesCfb = new aesjs.ModeOfOperation.cfb(key, iv, segmentSize);
var encryptedBytes = aesCfb.encrypt(textBytes);
 
// To print or store the binary data, you may convert it to hex
var encryptedHex = aesjs.utils.hex.fromBytes(encryptedBytes);
console.log(encryptedHex);
// "55e3af2638c560b4fdb9d26a630733ea60197ec23deb85b1f60f71f10409ce27"
 
// When ready to decrypt the hex string, convert it back to bytes
var encryptedBytes = aesjs.utils.hex.toBytes(encryptedHex);
 
// The cipher feedback mode of operation maintains internal state,
// so to decrypt a new instance must be instantiated.
var aesCfb = new aesjs.ModeOfOperation.cfb(key, iv, 8);
var decryptedBytes = aesCfb.decrypt(encryptedBytes);
 
// Convert our bytes back into text
var decryptedText = aesjs.utils.utf8.fromBytes(decryptedBytes);
console.log(decryptedText);
// "TextMustBeAMultipleOfSegmentSize"

OFB – 输出反馈

// An example 128-bit key
var key = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 ];
 
// The initialization vector (must be 16 bytes)
var iv = [ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,35, 36 ];
 
// Convert text to bytes
var text = 'Text may be any length you wish, no padding is required.';
var textBytes = aesjs.utils.utf8.toBytes(text);
 
var aesOfb = new aesjs.ModeOfOperation.ofb(key, iv);
var encryptedBytes = aesOfb.encrypt(textBytes);
 
// To print or store the binary data, you may convert it to hex
var encryptedHex = aesjs.utils.hex.fromBytes(encryptedBytes);
console.log(encryptedHex);
// "55e3af2655dd72b9f32456042f39bae9accff6259159e608be55a1aa313c598d
//  b4b18406d89c83841c9d1af13b56de8eda8fcfe9ec8e75e8"
 
// When ready to decrypt the hex string, convert it back to bytes
var encryptedBytes = aesjs.utils.hex.toBytes(encryptedHex);
 
// The output feedback mode of operation maintains internal state,
// so to decrypt a new instance must be instantiated.
var aesOfb = new aesjs.ModeOfOperation.ofb(key, iv);
var decryptedBytes = aesOfb.decrypt(encryptedBytes);
 
// Convert our bytes back into text
var decryptedText = aesjs.utils.utf8.fromBytes(decryptedBytes);
console.log(decryptedText);
// "Text may be any length you wish, no padding is required."

ECB – 电子密码本(不推荐)

推荐这种模式由于对于给定的密钥,相同的明文块输入会产生相同的密文块输出,因此这种操作模式可能会泄漏数据,例如模式。有关更多详细信息和示例,请参阅维基百科文章电子密码本

// An example 128-bit key
var key = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 ];
 
// Convert text to bytes
var text = 'TextMustBe16Byte';
var textBytes = aesjs.utils.utf8.toBytes(text);
 
var aesEcb = new aesjs.ModeOfOperation.ecb(key);
var encryptedBytes = aesEcb.encrypt(textBytes);
 
// To print or store the binary data, you may convert it to hex
var encryptedHex = aesjs.utils.hex.fromBytes(encryptedBytes);
console.log(encryptedHex);
// "a7d93b35368519fac347498dec18b458"
 
// When ready to decrypt the hex string, convert it back to bytes
var encryptedBytes = aesjs.utils.hex.toBytes(encryptedHex);
 
// Since electronic codebook does not store state, we can
// reuse the same instance.
//var aesEcb = new aesjs.ModeOfOperation.ecb(key);
var decryptedBytes = aesEcb.decrypt(encryptedBytes);
 
// Convert our bytes back into text
var decryptedText = aesjs.utils.utf8.fromBytes(decryptedBytes);
console.log(decryptedText);
// "TextMustBe16Byte"

块密码

您通常应该使用上述常用操作模式之一。使用ECB也可以直接使用分组密码算法,因为该操作模式只是一个薄包装。

但这对于尝试自定义操作模式或使用分组密码算法可能很有用。

 
// the AES block cipher algorithm works on 16 byte bloca ks, no more, no less
var text = "ABlockIs16Bytes!";
var textAsBytes = aesjs.utils.utf8.toBytes(text)
console.log(textAsBytes);
// [65, 66, 108, 111, 99, 107, 73, 115, 49, 54, 66, 121, 116, 101, 115, 33]
 
// create an instance of the block cipher algorithm
var key = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9, 3];
var aes = new aesjs.AES(key);
 
// encrypt...
var encryptedBytes = aes.encrypt(textAsBytes);
console.log(encryptedBytes);
// [136, 15, 199, 174, 118, 133, 233, 177, 143, 47, 42, 211, 96, 55, 107, 109] 
 
// To print or store the binary data, you may convert it to hex
var encryptedHex = aesjs.utils.hex.fromBytes(encryptedBytes);
console.log(encryptedHex);
// "880fc7ae7685e9b18f2f2ad360376b6d"
 
// When ready to decrypt the hex string, convert it back to bytes
var encryptedBytes = aesjs.utils.hex.toBytes(encryptedHex);
 
// decrypt...
var decryptedBytes = aes.decrypt(encryptedBytes);
console.log(decryptedBytes);
// [65, 66, 108, 111, 99, 107, 73, 115, 49, 54, 66, 121, 116, 101, 115, 33]
 
 
// decode the bytes back into our original text
var decryptedText = aesjs.utils.utf8.fromBytes(decryptedBytes);
console.log(decryptedText);
// "ABlockIs16Bytes!"

笔记

什么是钥匙

对于许多刚开始使用加密的人来说,这似乎是一个困惑点。您可以将密钥视为“密码”但是,这些算法要求“密码”具有特定长度。

对于 AES,存在三种可能的密钥长度:128 位(16 字节)、192 位(24 字节)或 256 位(32 字节)。创建 AES 对象时,会自动检测密钥大小,因此传入正确长度的密钥非常重要。

通常,您希望提供任意长度的密码,例如,易于记住或写下的密码。在这些情况下,您必须想出一种方法将密码转换为特定长度的密钥。一个基于口令的密钥导出函数(PBKDF)是专为这一确切目的的算法。

这是一个示例,使用流行的(可能已经过时?)pbkdf2:

var pbkdf2 = require('pbkdf2');
 
var key_128 = pbkdf2.pbkdf2Sync('password', 'salt', 1, 128 / 8, 'sha512');
var key_192 = pbkdf2.pbkdf2Sync('password', 'salt', 1, 192 / 8, 'sha512');
var key_256 = pbkdf2.pbkdf2Sync('password', 'salt', 1, 256 / 8, 'sha512');

另一种可能性是使用散列函数,例如 SHA256 来散列密码,但这种方法容易受到Rainbow Attacks 的攻击,除非您使用salt

表现

去做…

测试

test/test-vectors.json已从已知的正确实现pycrypto生成 ( )测试套件要生成新的测试向量,请运行python generate-tests.py

要运行 node.js 测试套件:

npm test

要运行 Web 浏览器测试,请test/test.html在浏览器中打开该文件。

常问问题

如何获得我添加的问题?

如有任何问题、建议、意见等,请发送电子邮件至aes-js@ricmoo.com

捐款

显然,它都是在 MIT 许可下获得许可的,所以请随意使用它;但如果你想请我喝杯咖啡,我不会抱怨的。=)

  • 比特币—— 1K1Ax9t6uJmjE4X5xcoVuyVTsiLrYRqe2P
  • 以太坊 – 0x70bDC274028F3f391E398dF8e3977De64FEcBf04
项目issue数量: 23

项目贡献人员列表:


极客公园 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:aes-js中文文档|aes-js js中文教程|解析
喜欢 (0)
.excerpt .focus {display:none}