Skip to content

Commit 8ac229a

Browse files
committed
Updated readme for 3.x update.
1 parent e27b99d commit 8ac229a

File tree

1 file changed

+141
-41
lines changed

1 file changed

+141
-41
lines changed

README.md

Lines changed: 141 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,51 @@ Features
1313
- Supports all common modes of operation (CBC, CFB, CTR, ECB and OFB)
1414
- Works in either node.js or web browsers
1515

16+
Migrating from 2.x to 3.x
17+
-------------------------
18+
19+
The utility functions have been renamed in the 3.x branch, since they were causing a great deal of confusion converting between bytes and string.
20+
21+
The examples have also been updated to encode binary data as printable hex strings.
22+
23+
**Strings and Bytes**
24+
25+
Strings should **NOT** be used as keys. UTF-8 allows variable length, multi-byte characters, so a string that is 16 *characters* long may not be 16 *bytes* long.
26+
27+
Also, UTF8 should **NOT** be used to store arbitrary binary data as it is a *string* encoding format, not a *binary* encoding format.
28+
29+
```javascript
30+
// aesjs.util.convertStringToBytes(aString)
31+
// Becomes:
32+
aesjs.utils.utf8.toBytes(aString)
33+
34+
35+
// aesjs.util.convertBytesToString(aString)
36+
// Becomes:
37+
aesjs.utils.utf8.fromBytes(aString)
38+
```
39+
40+
**Bytes and Hex strings**
41+
42+
Binary data, such as encrypted bytes, can safely be stored and printed as hexidecimal strings.
43+
44+
```javascript
45+
// aesjs.util.convertStringToBytes(aString, 'hex')
46+
// Becomes:
47+
aesjs.utils.hex.toBytes(aString)
48+
49+
50+
// aesjs.util.convertBytesToString(aString, 'hex')
51+
// Becomes:
52+
aesjs.utils.hex.fromBytes(aString)
53+
```
54+
55+
**Typed Arrays**
56+
57+
The 3.x and above versions of aes-js use [Uint8Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) instead of Array, which reduces code size when used with Browserify (it no longer pulls in Buffer) and is also about **twice** the speed.
58+
59+
However, if you need to support browsers older than IE 10, you should continue using version 2.x.
60+
1661

1762
API
1863
===
@@ -36,13 +81,15 @@ var aesjs = require('aes-js');
3681
To use `aes-js` in a web page, add the following:
3782

3883
```html
39-
<script type="text/javascript" src="https://rawgit.com/ricmoo/aes-js/master/index.js"></script>
84+
<script type="text/javascript" src="https://cdn.rawgit.com/ricmoo/aes-js/e27b99df/index.js"></script>
4085
```
4186

4287
Keys
4388
----
4489

45-
All keys must be 128 bits (16 bytes), 192 bits (24 bytes) or 256 bits (32 bytes) long. The API's work on either arrays or `Buffer` objects.
90+
All keys must be 128 bits (16 bytes), 192 bits (24 bytes) or 256 bits (32 bytes) long.
91+
92+
The library work with `Array`, `Uint8Array` and `Buffer` objects as well as any *array-like* object (i.e. must have a `length` property, and have a valid byte value for each entry).
4693

4794
```javascript
4895
// 128-bit, 192-bit and 256-bit keys
@@ -53,18 +100,19 @@ var key_256 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
53100
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
54101
29, 30, 31];
55102

56-
// or, similarly, with buffers (node.js only):
57-
var key_128 = new Buffer([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
58-
var key_192 = new Buffer([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
59-
16, 17, 18, 19, 20, 21, 22, 23]);
60-
var key_256 = new Buffer([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
61-
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
62-
29, 30, 31]);
103+
// or, you may use Uint8Array:
104+
var key_128_array = new Uint8Array(key_128);
105+
var key_192_array = new Uint8Array(key_192);
106+
var key_258_array = new Uint8Array(key_256);
63107

108+
// or, you may use Buffer in node.js:
109+
var key_128_buffer = new Buffer(key_128);
110+
var key_192_buffer = new Buffer(key_192);
111+
var key_258_buffer = new Buffer(key_256);
64112
```
65113

66114

67-
To generate keys from simple-to-remember passwords, consider using a password-based key-derivation function such as [scrypt](https://www.npmjs.com/search?q=scrypt) or [bcrypt](https://www.npmjs.com/search?q=bcrypt).
115+
To generate keys from simple-to-remember passwords, consider using a password-based key-derivation function such as [scrypt](https://www.npmjs.com/package/scrypt-js) or [bcrypt](https://www.npmjs.com/search?q=bcrypt).
68116

69117

70118
Common Modes of Operation
@@ -75,23 +123,33 @@ There are several modes of operations, each with various pros and cons. In gener
75123
### CTR - Counter (recommended)
76124

77125
```javascript
78-
var key = aesjs.util.convertStringToBytes("Example128BitKey");
126+
// An example 128-bit key (16 bytes * 8 bits/byte = 128 bits)
127+
var key = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 ];
79128

80129
// Convert text to bytes
81130
var text = 'Text may be any length you wish, no padding is required.';
82-
var textBytes = aesjs.util.convertStringToBytes(text);
131+
var textBytes = aesjs.utils.utf8.toBytes(text);
83132

84-
// The counter is optional, and if omitted will begin at 0
133+
// The counter is optional, and if omitted will begin at 1
85134
var aesCtr = new aesjs.ModeOfOperation.ctr(key, new aesjs.Counter(5));
86135
var encryptedBytes = aesCtr.encrypt(textBytes);
87136

137+
// To print or store the binary data, you may convert it to hex
138+
var encryptedHex = aesjs.utils.hex.fromBytes(encryptedBytes);
139+
console.log(encryptedHex);
140+
// "a338eda3874ed884b6199150d36f49988c90f5c47fe7792b0cf8c7f77eeffd87
141+
// ea145b73e82aefcf2076f881c88879e4e25b1d7b24ba2788"
142+
143+
// When ready to decrypt the hex string, convert it back to bytes
144+
var encryptedBytes = aesjs.utils.hex.toBytes(encryptedHex);
145+
88146
// The counter mode of operation maintains internal state, so to
89147
// decrypt a new instance must be instantiated.
90148
var aesCtr = new aesjs.ModeOfOperation.ctr(key, new aesjs.Counter(5));
91149
var decryptedBytes = aesCtr.decrypt(encryptedBytes);
92150

93151
// Convert our bytes back into text
94-
var decryptedText = aesjs.util.convertBytesToString(decryptedBytes);
152+
var decryptedText = aesjs.utils.utf8.fromBytes(decryptedBytes);
95153
console.log(decryptedText);
96154
// "Text may be any length you wish, no padding is required."
97155
```
@@ -100,25 +158,34 @@ console.log(decryptedText);
100158
### CBC - Cipher-Block Chaining (recommended)
101159

102160
```javascript
103-
var key = aesjs.util.convertStringToBytes("Example128BitKey");
161+
// An example 128-bit key
162+
var key = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 ];
104163

105-
// The initialization vector, which must be 16 bytes
106-
var iv = aesjs.util.convertStringToBytes("IVMustBe16Bytes.");
164+
// The initialization vector (must be 16 bytes)
165+
var iv = [ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,35, 36 ];
107166

108-
// Convert text to bytes
167+
// Convert text to bytes (text must be a multiple of 16 bytes)
109168
var text = 'TextMustBe16Byte';
110-
var textBytes = aesjs.util.convertStringToBytes(text);
169+
var textBytes = aesjs.utils.utf8.toBytes(text);
111170

112171
var aesCbc = new aesjs.ModeOfOperation.cbc(key, iv);
113172
var encryptedBytes = aesCbc.encrypt(textBytes);
114173

174+
// To print or store the binary data, you may convert it to hex
175+
var encryptedHex = aesjs.utils.hex.fromBytes(encryptedBytes);
176+
console.log(encryptedHex);
177+
// "104fb073f9a131f2cab49184bb864ca2"
178+
179+
// When ready to decrypt the hex string, convert it back to bytes
180+
var encryptedBytes = aesjs.utils.hex.toBytes(encryptedHex);
181+
115182
// The cipher-block chaining mode of operation maintains internal
116183
// state, so to decrypt a new instance must be instantiated.
117184
var aesCbc = new aesjs.ModeOfOperation.cbc(key, iv);
118185
var decryptedBytes = aesCbc.decrypt(encryptedBytes);
119186

120187
// Convert our bytes back into text
121-
var decryptedText = aesjs.util.convertBytesToString(decryptedBytes);
188+
var decryptedText = aesjs.utils.utf8.fromBytes(decryptedBytes);
122189
console.log(decryptedText);
123190
// "TextMustBe16Byte"
124191
```
@@ -127,26 +194,36 @@ console.log(decryptedText);
127194
### CFB - Cipher Feedback
128195

129196
```javascript
130-
var key = aesjs.util.convertStringToBytes("Example128BitKey");
197+
// An example 128-bit key
198+
var key = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 ];
131199

132-
// The initialization vector, which must be 16 bytes
133-
var iv = aesjs.util.convertStringToBytes("IVMustBe16Bytes.");
200+
// The initialization vector (must be 16 bytes)
201+
var iv = [ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,35, 36 ];
134202

135-
// Convert text to bytes
203+
// Convert text to bytes (must be a multiple of the segment size you choose below)
136204
var text = 'TextMustBeAMultipleOfSegmentSize';
137-
var textBytes = aesjs.util.convertStringToBytes(text);
205+
var textBytes = aesjs.utils.utf8.toBytes(text);
138206

139207
// The segment size is optional, and defaults to 1
140-
var aesCfb = new aesjs.ModeOfOperation.cfb(key, iv, 8);
208+
var segmentSize = 8;
209+
var aesCfb = new aesjs.ModeOfOperation.cfb(key, iv, segmentSize);
141210
var encryptedBytes = aesCfb.encrypt(textBytes);
142211

212+
// To print or store the binary data, you may convert it to hex
213+
var encryptedHex = aesjs.utils.hex.fromBytes(encryptedBytes);
214+
console.log(encryptedHex);
215+
// "55e3af2638c560b4fdb9d26a630733ea60197ec23deb85b1f60f71f10409ce27"
216+
217+
// When ready to decrypt the hex string, convert it back to bytes
218+
var encryptedBytes = aesjs.utils.hex.toBytes(encryptedHex);
219+
143220
// The cipher feedback mode of operation maintains internal state,
144221
// so to decrypt a new instance must be instantiated.
145222
var aesCfb = new aesjs.ModeOfOperation.cfb(key, iv, 8);
146223
var decryptedBytes = aesCfb.decrypt(encryptedBytes);
147224

148225
// Convert our bytes back into text
149-
var decryptedText = aesjs.util.convertBytesToString(decryptedBytes);
226+
var decryptedText = aesjs.utils.utf8.fromBytes(decryptedBytes);
150227
console.log(decryptedText);
151228
// "TextMustBeAMultipleOfSegmentSize"
152229
```
@@ -155,25 +232,35 @@ console.log(decryptedText);
155232
### OFB - Output Feedback
156233

157234
```javascript
158-
var key = aesjs.util.convertStringToBytes("Example128BitKey");
235+
// An example 128-bit key
236+
var key = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 ];
159237

160-
// The initialization vector, which must be 16 bytes
161-
var iv = aesjs.util.convertStringToBytes("IVMustBe16Bytes.");
238+
// The initialization vector (must be 16 bytes)
239+
var iv = [ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,35, 36 ];
162240

163241
// Convert text to bytes
164242
var text = 'Text may be any length you wish, no padding is required.';
165-
var textBytes = aesjs.util.convertStringToBytes(text);
243+
var textBytes = aesjs.utils.utf8.toBytes(text);
166244

167245
var aesOfb = new aesjs.ModeOfOperation.ofb(key, iv);
168246
var encryptedBytes = aesOfb.encrypt(textBytes);
169247

248+
// To print or store the binary data, you may convert it to hex
249+
var encryptedHex = aesjs.utils.hex.fromBytes(encryptedBytes);
250+
console.log(encryptedHex);
251+
// "55e3af2655dd72b9f32456042f39bae9accff6259159e608be55a1aa313c598d
252+
// b4b18406d89c83841c9d1af13b56de8eda8fcfe9ec8e75e8"
253+
254+
// When ready to decrypt the hex string, convert it back to bytes
255+
var encryptedBytes = aesjs.utils.hex.toBytes(encryptedHex);
256+
170257
// The output feedback mode of operation maintains internal state,
171258
// so to decrypt a new instance must be instantiated.
172259
var aesOfb = new aesjs.ModeOfOperation.ofb(key, iv);
173260
var decryptedBytes = aesOfb.decrypt(encryptedBytes);
174261

175262
// Convert our bytes back into text
176-
var decryptedText = aesjs.util.convertBytesToString(decryptedBytes);
263+
var decryptedText = aesjs.utils.utf8.fromBytes(decryptedBytes);
177264
console.log(decryptedText);
178265
// "Text may be any length you wish, no padding is required."
179266
```
@@ -184,22 +271,31 @@ console.log(decryptedText);
184271
This mode is **not** recommended. Since, for a given key, the same plaintext block in produces the same ciphertext block out, this mode of operation can leak data, such as patterns. For more details and examples, see the Wikipedia article, [Electronic Codebook](http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_Codebook_.28ECB.29).
185272

186273
```javascript
187-
var key = aesjs.util.convertStringToBytes("Example128BitKey");
274+
// An example 128-bit key
275+
var key = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 ];
188276

189277
// Convert text to bytes
190278
var text = 'TextMustBe16Byte';
191-
var textBytes = aesjs.util.convertStringToBytes(text);
279+
var textBytes = aesjs.utils.utf8.toBytes(text);
192280

193281
var aesEcb = new aesjs.ModeOfOperation.ecb(key);
194282
var encryptedBytes = aesEcb.encrypt(textBytes);
195283

284+
// To print or store the binary data, you may convert it to hex
285+
var encryptedHex = aesjs.utils.hex.fromBytes(encryptedBytes);
286+
console.log(encryptedHex);
287+
// "a7d93b35368519fac347498dec18b458"
288+
289+
// When ready to decrypt the hex string, convert it back to bytes
290+
var encryptedBytes = aesjs.utils.hex.toBytes(encryptedHex);
291+
196292
// Since electronic codebook does not store state, we can
197293
// reuse the same instance.
198294
//var aesEcb = new aesjs.ModeOfOperation.ecb(key);
199295
var decryptedBytes = aesEcb.decrypt(encryptedBytes);
200296

201297
// Convert our bytes back into text
202-
var decryptedText = aesjs.util.convertBytesToString(decryptedBytes);
298+
var decryptedText = aesjs.utils.utf8.fromBytes(decryptedBytes);
203299
console.log(decryptedText);
204300
// "TextMustBe16Byte"
205301
```
@@ -217,21 +313,26 @@ But this might be useful to experiment with custom modes of operation or play wi
217313

218314
// the AES block cipher algorithm works on 16 byte bloca ks, no more, no less
219315
var text = "ABlockIs16Bytes!";
220-
var textAsBytes = aesjs.util.convertStringToBytes(text)
316+
var textAsBytes = aesjs.utils.utf8.toBytes(text)
221317
console.log(textAsBytes);
222318
// [65, 66, 108, 111, 99, 107, 73, 115, 49, 54, 66, 121, 116, 101, 115, 33]
223319

224-
225320
// create an instance of the block cipher algorithm
226321
var key = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9, 3];
227322
var aes = new aesjs.AES(key);
228323

229-
230324
// encrypt...
231325
var encryptedBytes = aes.encrypt(textAsBytes);
232326
console.log(encryptedBytes);
233327
// [136, 15, 199, 174, 118, 133, 233, 177, 143, 47, 42, 211, 96, 55, 107, 109]
234328

329+
// To print or store the binary data, you may convert it to hex
330+
var encryptedHex = aesjs.utils.hex.fromBytes(encryptedBytes);
331+
console.log(encryptedHex);
332+
// "880fc7ae7685e9b18f2f2ad360376b6d"
333+
334+
// When ready to decrypt the hex string, convert it back to bytes
335+
var encryptedBytes = aesjs.utils.hex.toBytes(encryptedHex);
235336

236337
// decrypt...
237338
var decryptedBytes = aes.decrypt(encryptedBytes);
@@ -240,7 +341,7 @@ console.log(decryptedBytes);
240341

241342

242343
// decode the bytes back into our original text
243-
var decryptedText = aesjs.util.convertBytesToString(decryptedBytes);
344+
var decryptedText = aesjs.utils.utf8.fromBytes(decryptedBytes);
244345
console.log(decryptedText);
245346
// "ABlockIs16Bytes!"
246347
```
@@ -302,5 +403,4 @@ Donations
302403
Obviously, it's all licensed under the MIT license, so use it as you wish; but if you'd like to buy me a coffee, I won't complain. =)
303404

304405
- Bitcoin - `1K1Ax9t6uJmjE4X5xcoVuyVTsiLrYRqe2P`
305-
- Dogecoin - `DFhgqVuaboxFnGQssyX84ZuV5r6aBRz8QJ`
306-
- Testnet3 - `n1F2Eb6cknqqknUPp7m9oBNMgXFuaDowvF`
406+
- Ethereum - `0x70bDC274028F3f391E398dF8e3977De64FEcBf04`

0 commit comments

Comments
 (0)