@lindorm/aes 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +285 -0
- package/dist/utils/is-aes.d.ts.map +1 -1
- package/dist/utils/is-aes.js +2 -1
- package/dist/utils/is-aes.js.map +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [0.5.1](https://github.com/lindorm-io/monorepo/compare/@lindorm/aes@0.5.0...@lindorm/aes@0.5.1) (2025-07-02)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
- amend bug in aes utility ([7437e8e](https://github.com/lindorm-io/monorepo/commit/7437e8e0f047bb0995b8a8c0e6929c9cc368d592))
|
|
11
|
+
|
|
6
12
|
# [0.5.0](https://github.com/lindorm-io/monorepo/compare/@lindorm/aes@0.4.2...@lindorm/aes@0.5.0) (2025-06-17)
|
|
7
13
|
|
|
8
14
|
### Bug Fixes
|
package/README.md
CHANGED
|
@@ -1 +1,286 @@
|
|
|
1
1
|
# @lindorm/aes
|
|
2
|
+
|
|
3
|
+
A comprehensive TypeScript library for AES encryption and decryption with support for multiple key algorithms, encryption modes, and flexible output formats.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @lindorm/aes
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- **Multiple Key Algorithms**: Support for EC, OKP, RSA, and symmetric keys
|
|
14
|
+
- **Key Derivation**: HKDF, PBKDF2, and direct key usage
|
|
15
|
+
- **Key Wrapping**: ECB and GCM key wrapping modes
|
|
16
|
+
- **Multiple Encryption Modes**: CBC-HMAC and GCM authenticated encryption
|
|
17
|
+
- **Flexible Output Formats**: Encoded strings, structured records, serialized objects, and tokenized strings
|
|
18
|
+
- **Type Safety**: Full TypeScript support with comprehensive type definitions
|
|
19
|
+
- **Content Type Detection**: Automatic detection and handling of different data types
|
|
20
|
+
- **Verification Methods**: Built-in verification and assertion utilities
|
|
21
|
+
|
|
22
|
+
## Supported Algorithms
|
|
23
|
+
|
|
24
|
+
### Key Algorithms
|
|
25
|
+
- **ECDH-ES**: Elliptic Curve Diffie-Hellman Ephemeral Static
|
|
26
|
+
- **ECDH-ES+A128KW**: ECDH-ES with AES-128 Key Wrap
|
|
27
|
+
- **ECDH-ES+A128GCMKW**: ECDH-ES with AES-128 GCM Key Wrap
|
|
28
|
+
- **A128KW**: AES-128 Key Wrap
|
|
29
|
+
- **A128GCMKW**: AES-128 GCM Key Wrap
|
|
30
|
+
- **PBES2-HS256+A128KW**: PBKDF2 with HMAC SHA-256 and AES-128 Key Wrap
|
|
31
|
+
- **RSA-OAEP-256**: RSA OAEP with SHA-256
|
|
32
|
+
|
|
33
|
+
### Encryption Modes
|
|
34
|
+
- **A128CBC-HS256**: AES-128 CBC with HMAC SHA-256
|
|
35
|
+
- **A128GCM**: AES-128 GCM (default)
|
|
36
|
+
- **A192GCM**: AES-192 GCM
|
|
37
|
+
- **A256GCM**: AES-256 GCM
|
|
38
|
+
|
|
39
|
+
## Basic Usage
|
|
40
|
+
|
|
41
|
+
### Setup
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { AesKit } from '@lindorm/aes';
|
|
45
|
+
import { KryptosKit } from '@lindorm/kryptos';
|
|
46
|
+
|
|
47
|
+
// Generate or load a cryptographic key
|
|
48
|
+
const kryptos = KryptosKit.generate.auto({ algorithm: 'ECDH-ES' });
|
|
49
|
+
|
|
50
|
+
// Create AES kit instance
|
|
51
|
+
const aesKit = new AesKit({
|
|
52
|
+
kryptos,
|
|
53
|
+
encryption: 'A256GCM' // Optional: defaults to A256GCM or kryptos.encryption
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Encryption Modes
|
|
58
|
+
|
|
59
|
+
The AES kit supports four different output formats:
|
|
60
|
+
|
|
61
|
+
#### 1. Encoded (Default)
|
|
62
|
+
Returns a base64-encoded string - simplest format for storage/transmission:
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
const encrypted = aesKit.encrypt('Hello World'); // Returns base64 string
|
|
66
|
+
const decrypted = aesKit.decrypt(encrypted); // 'Hello World'
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
#### 2. Record
|
|
70
|
+
Returns a structured object with Buffer values - useful for direct manipulation:
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
const encrypted = aesKit.encrypt('Hello World', 'record');
|
|
74
|
+
// Returns: AesEncryptionRecord with Buffer properties
|
|
75
|
+
|
|
76
|
+
console.log(encrypted.keyId); // Key identifier
|
|
77
|
+
console.log(encrypted.algorithm); // 'ECDH-ES'
|
|
78
|
+
console.log(encrypted.encryption); // 'A256GCM'
|
|
79
|
+
console.log(encrypted.content); // Buffer containing encrypted data
|
|
80
|
+
|
|
81
|
+
const decrypted = aesKit.decrypt(encrypted); // 'Hello World'
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
#### 3. Serialised
|
|
85
|
+
Returns a structured object with string values - JSON-serializable:
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
const encrypted = aesKit.encrypt('Hello World', 'serialised');
|
|
89
|
+
// Returns: SerialisedAesEncryption with base64 string properties
|
|
90
|
+
|
|
91
|
+
const json = JSON.stringify(encrypted); // Can be serialized
|
|
92
|
+
const parsed = JSON.parse(json);
|
|
93
|
+
const decrypted = aesKit.decrypt(parsed); // 'Hello World'
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
#### 4. Tokenised
|
|
97
|
+
Returns a compact token format with embedded metadata:
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
const encrypted = aesKit.encrypt('Hello World', 'tokenised');
|
|
101
|
+
// Returns: '$A256GCM$v=1&alg=ECDH-ES&...$base64content$'
|
|
102
|
+
|
|
103
|
+
const decrypted = aesKit.decrypt(encrypted); // 'Hello World'
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Content Types
|
|
107
|
+
|
|
108
|
+
The library automatically handles different content types:
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
// String content
|
|
112
|
+
const text = aesKit.encrypt('Hello World');
|
|
113
|
+
|
|
114
|
+
// JSON objects
|
|
115
|
+
const obj = aesKit.encrypt({ message: 'Hello', count: 42 });
|
|
116
|
+
|
|
117
|
+
// Arrays
|
|
118
|
+
const arr = aesKit.encrypt([1, 2, 3]);
|
|
119
|
+
|
|
120
|
+
// Buffers
|
|
121
|
+
const buf = aesKit.encrypt(Buffer.from('binary data'));
|
|
122
|
+
|
|
123
|
+
// Numbers
|
|
124
|
+
const num = aesKit.encrypt(42);
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Verification and Assertion
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
const encrypted = aesKit.encrypt('Hello World');
|
|
131
|
+
|
|
132
|
+
// Verify without throwing
|
|
133
|
+
const isValid = aesKit.verify('Hello World', encrypted); // true
|
|
134
|
+
const isInvalid = aesKit.verify('Wrong data', encrypted); // false
|
|
135
|
+
|
|
136
|
+
// Assert with exception on failure
|
|
137
|
+
aesKit.assert('Hello World', encrypted); // Passes
|
|
138
|
+
aesKit.assert('Wrong data', encrypted); // Throws AesError
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Advanced Usage
|
|
142
|
+
|
|
143
|
+
### Custom Encryption Configuration
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
import { AesKit } from '@lindorm/aes';
|
|
147
|
+
import { KryptosKit } from '@lindorm/kryptos';
|
|
148
|
+
|
|
149
|
+
// RSA with OAEP padding
|
|
150
|
+
const rsaKey = KryptosKit.generate.rsa({
|
|
151
|
+
algorithm: 'RSA-OAEP-256',
|
|
152
|
+
modulusLength: 2048
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
const aesKit = new AesKit({
|
|
156
|
+
kryptos: rsaKey,
|
|
157
|
+
encryption: 'A256GCM'
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
// PBKDF2-based key derivation
|
|
161
|
+
const pbkdfKey = KryptosKit.generate.oct({
|
|
162
|
+
algorithm: 'PBES2-HS256+A128KW',
|
|
163
|
+
length: 256
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
const pbkdfAes = new AesKit({
|
|
167
|
+
kryptos: pbkdfKey,
|
|
168
|
+
encryption: 'A128CBC-HS256'
|
|
169
|
+
});
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Working with Different Key Types
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
// Elliptic Curve keys
|
|
176
|
+
const ecKey = KryptosKit.generate.ec({
|
|
177
|
+
algorithm: 'ECDH-ES+A128GCMKW',
|
|
178
|
+
curve: 'P-256'
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// Edwards Curve keys (OKP)
|
|
182
|
+
const okpKey = KryptosKit.generate.okp({
|
|
183
|
+
algorithm: 'ECDH-ES',
|
|
184
|
+
curve: 'X25519'
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
// Symmetric keys
|
|
188
|
+
const symmetricKey = KryptosKit.generate.oct({
|
|
189
|
+
algorithm: 'A128GCMKW',
|
|
190
|
+
length: 256
|
|
191
|
+
});
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Utility Functions
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
import { parseAes, isAesTokenised } from '@lindorm/aes';
|
|
198
|
+
|
|
199
|
+
// Parse any AES format to standard record
|
|
200
|
+
const record = parseAes(encryptedData); // Works with any format
|
|
201
|
+
|
|
202
|
+
// Check if string is tokenised format
|
|
203
|
+
const isToken = isAesTokenised('$A256GCM$v=1&alg=ECDH-ES$...$'); // true
|
|
204
|
+
const isNotToken = isAesTokenised('base64string'); // false
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Type Definitions
|
|
208
|
+
|
|
209
|
+
### Core Types
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
interface AesKitOptions {
|
|
213
|
+
kryptos: IKryptos; // Cryptographic key instance
|
|
214
|
+
encryption?: KryptosEncryption; // Encryption mode (defaults to A256GCM)
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
type AesContent = Array<any> | Buffer | Dict | number | string;
|
|
218
|
+
|
|
219
|
+
type AesEncryptionMode = 'encoded' | 'record' | 'serialised' | 'tokenised';
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Record Types
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
interface AesEncryptionRecord {
|
|
226
|
+
algorithm: KryptosAlgorithm; // Key algorithm used
|
|
227
|
+
authTag: Buffer; // Authentication tag
|
|
228
|
+
content: Buffer; // Encrypted content
|
|
229
|
+
contentType: AesContentType; // Original content type
|
|
230
|
+
encryption: KryptosEncryption; // Encryption mode
|
|
231
|
+
hkdfSalt?: Buffer; // HKDF salt (if applicable)
|
|
232
|
+
initialisationVector: Buffer; // IV for encryption
|
|
233
|
+
keyId: string; // Key identifier
|
|
234
|
+
pbkdfIterations?: number; // PBKDF2 iterations (if applicable)
|
|
235
|
+
pbkdfSalt?: Buffer; // PBKDF2 salt (if applicable)
|
|
236
|
+
publicEncryptionJwk?: PublicEncryptionJwk; // Public key (for ECDH)
|
|
237
|
+
version: number; // Format version
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
interface SerialisedAesEncryption {
|
|
241
|
+
// Same as AesEncryptionRecord but with base64 strings instead of Buffers
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## Error Handling
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
import { AesError } from '@lindorm/aes';
|
|
249
|
+
|
|
250
|
+
try {
|
|
251
|
+
const decrypted = aesKit.decrypt(invalidData);
|
|
252
|
+
} catch (error) {
|
|
253
|
+
if (error instanceof AesError) {
|
|
254
|
+
console.log('AES operation failed:', error.message);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## Integration with Kryptos
|
|
260
|
+
|
|
261
|
+
The AES library integrates seamlessly with `@lindorm/kryptos` for key management:
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
import { AesKit } from '@lindorm/aes';
|
|
265
|
+
import { Amphora } from '@lindorm/amphora';
|
|
266
|
+
|
|
267
|
+
// Use with key storage
|
|
268
|
+
const amphora = new Amphora({ domain: 'https://example.com', logger });
|
|
269
|
+
await amphora.setup();
|
|
270
|
+
|
|
271
|
+
// Find encryption key
|
|
272
|
+
const kryptos = await amphora.find({ use: 'enc', algorithm: 'ECDH-ES' });
|
|
273
|
+
|
|
274
|
+
const aesKit = new AesKit({ kryptos });
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
## Performance Considerations
|
|
278
|
+
|
|
279
|
+
- **Encoded mode**: Fastest for simple use cases
|
|
280
|
+
- **Record mode**: Best for direct Buffer manipulation
|
|
281
|
+
- **Serialised mode**: Optimal for JSON storage/transmission
|
|
282
|
+
- **Tokenised mode**: Most compact for URL-safe tokens
|
|
283
|
+
|
|
284
|
+
## License
|
|
285
|
+
|
|
286
|
+
AGPL-3.0-or-later
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"is-aes.d.ts","sourceRoot":"","sources":["../../src/utils/is-aes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAExE,eAAO,MAAM,eAAe,GAC1B,MAAM,mBAAmB,GAAG,uBAAuB,KAClD,IAAI,IAAI,mBAAmE,CAAC;AAE/E,eAAO,MAAM,mBAAmB,GAC9B,SAAS,mBAAmB,GAAG,uBAAuB,KACrD,OAAO,IAAI,uBACqC,CAAC;AAEpD,eAAO,MAAM,cAAc,GAAI,QAAQ,MAAM,KAAG,
|
|
1
|
+
{"version":3,"file":"is-aes.d.ts","sourceRoot":"","sources":["../../src/utils/is-aes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAExE,eAAO,MAAM,eAAe,GAC1B,MAAM,mBAAmB,GAAG,uBAAuB,KAClD,IAAI,IAAI,mBAAmE,CAAC;AAE/E,eAAO,MAAM,mBAAmB,GAC9B,SAAS,mBAAmB,GAAG,uBAAuB,KACrD,OAAO,IAAI,uBACqC,CAAC;AAEpD,eAAO,MAAM,cAAc,GAAI,QAAQ,MAAM,KAAG,OAKvB,CAAC"}
|
package/dist/utils/is-aes.js
CHANGED
|
@@ -6,7 +6,8 @@ const isAesBufferData = (data) => Object.values(data).some((x) => (0, is_1.isBuf
|
|
|
6
6
|
exports.isAesBufferData = isAesBufferData;
|
|
7
7
|
const isAesSerialisedData = (options) => Object.values(options).every((x) => !(0, is_1.isBuffer)(x));
|
|
8
8
|
exports.isAesSerialisedData = isAesSerialisedData;
|
|
9
|
-
const isAesTokenised = (string) =>
|
|
9
|
+
const isAesTokenised = (string) => (0, is_1.isString)(string) &&
|
|
10
|
+
string.startsWith("$") &&
|
|
10
11
|
string.endsWith("$") &&
|
|
11
12
|
string.includes("v=") &&
|
|
12
13
|
string.includes("alg=");
|
package/dist/utils/is-aes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"is-aes.js","sourceRoot":"","sources":["../../src/utils/is-aes.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"is-aes.js","sourceRoot":"","sources":["../../src/utils/is-aes.ts"],"names":[],"mappings":";;;AAAA,oCAAiD;AAG1C,MAAM,eAAe,GAAG,CAC7B,IAAmD,EACtB,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,aAAQ,EAAC,CAAC,CAAC,CAAC,CAAC;AAFlE,QAAA,eAAe,mBAEmD;AAExE,MAAM,mBAAmB,GAAG,CACjC,OAAsD,EAClB,EAAE,CACtC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAA,aAAQ,EAAC,CAAC,CAAC,CAAC,CAAC;AAHvC,QAAA,mBAAmB,uBAGoB;AAE7C,MAAM,cAAc,GAAG,CAAC,MAAc,EAAW,EAAE,CACxD,IAAA,aAAQ,EAAC,MAAM,CAAC;IAChB,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC;IACtB,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC;IACpB,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;IACrB,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AALb,QAAA,cAAc,kBAKD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lindorm/aes",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"license": "AGPL-3.0-or-later",
|
|
5
5
|
"author": "Jonn Nilsson",
|
|
6
6
|
"repository": {
|
|
@@ -30,12 +30,12 @@
|
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@lindorm/b64": "^0.1.6",
|
|
33
|
-
"@lindorm/errors": "^0.1.
|
|
33
|
+
"@lindorm/errors": "^0.1.9",
|
|
34
34
|
"@lindorm/is": "^0.1.8",
|
|
35
|
-
"@lindorm/kryptos": "^0.4.
|
|
35
|
+
"@lindorm/kryptos": "^0.4.1"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@lindorm/types": "^0.3.0"
|
|
39
39
|
},
|
|
40
|
-
"gitHead": "
|
|
40
|
+
"gitHead": "e66150efb6d7a4688bcece59481ab98d54865af3"
|
|
41
41
|
}
|