wilcocrypt 2.2.0 → 2.2.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/.github/ISSUE_TEMPLATE/bug.md +58 -64
- package/CHANGELOG.md +38 -0
- package/DOCS.md +286 -94
- package/README.md +15 -14
- package/SECURITY.md +12 -12
- package/package.json +11 -8
- package/src/cli.js +40 -37
- package/src/wilcocrypt.js +260 -53
- package/types/wilcocrypt.d.ts +189 -18
package/DOCS.md
CHANGED
|
@@ -13,6 +13,10 @@ Complete reference for the WilcoCrypt API, CLI, and binary format.
|
|
|
13
13
|
- [decryptData](#decryptdata)
|
|
14
14
|
- [encryptFile](#encryptfile)
|
|
15
15
|
- [decryptFile](#decryptfile)
|
|
16
|
+
- [encryptDataAsync](#encryptdataasync)
|
|
17
|
+
- [decryptDataAsync](#decryptdataasync)
|
|
18
|
+
- [encryptFileAsync](#encryptfileasync)
|
|
19
|
+
- [decryptFileAsync](#decryptfileasync)
|
|
16
20
|
- [encryptFileStream](#encryptfilestream)
|
|
17
21
|
- [decryptFileStream](#decryptfilestream)
|
|
18
22
|
- [Internal Namespace (`_`)](#internal-namespace-_)
|
|
@@ -37,24 +41,47 @@ Requires Node.js 18 or later (uses `stream/promises` and `fs/promises`).
|
|
|
37
41
|
## Quick Start
|
|
38
42
|
|
|
39
43
|
```js
|
|
40
|
-
import wilcocrypt from
|
|
44
|
+
import wilcocrypt from "wilcocrypt";
|
|
41
45
|
|
|
42
46
|
// Encrypt a Buffer
|
|
43
|
-
const data = Buffer.from(
|
|
44
|
-
const encrypted = wilcocrypt.encryptData(data,
|
|
47
|
+
const data = Buffer.from("Hello, world!");
|
|
48
|
+
const encrypted = wilcocrypt.encryptData(data, "my-password");
|
|
45
49
|
|
|
46
50
|
// Decrypt it back
|
|
47
|
-
const decrypted = wilcocrypt.decryptData(encrypted,
|
|
51
|
+
const decrypted = wilcocrypt.decryptData(encrypted, "my-password");
|
|
48
52
|
console.log(decrypted.toString()); // Hello, world!
|
|
49
53
|
|
|
50
54
|
// Encrypt a file (writes file.txt.enc)
|
|
51
|
-
wilcocrypt.encryptFile(
|
|
55
|
+
wilcocrypt.encryptFile("file.txt", "my-password");
|
|
52
56
|
|
|
53
57
|
// Decrypt a file (returns Buffer)
|
|
54
|
-
const contents = wilcocrypt.decryptFile(
|
|
58
|
+
const contents = wilcocrypt.decryptFile("file.txt.enc", "my-password");
|
|
55
59
|
|
|
56
60
|
// Decrypt a file directly to disk
|
|
57
|
-
wilcocrypt.decryptFile(
|
|
61
|
+
wilcocrypt.decryptFile("file.txt.enc", "my-password", "output.txt");
|
|
62
|
+
|
|
63
|
+
// Async API
|
|
64
|
+
const encryptedAsync = await wilcocrypt.encryptDataAsync(
|
|
65
|
+
Buffer.from("Hello!"),
|
|
66
|
+
"my-password",
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
const decryptedAsync = await wilcocrypt.decryptDataAsync(
|
|
70
|
+
encryptedAsync,
|
|
71
|
+
"my-password",
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
// Async file API
|
|
75
|
+
await wilcocrypt.encryptFileAsync(
|
|
76
|
+
"file.txt",
|
|
77
|
+
"my-password",
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
await wilcocrypt.decryptFileAsync(
|
|
81
|
+
"file.txt.enc",
|
|
82
|
+
"my-password",
|
|
83
|
+
"output.txt",
|
|
84
|
+
);
|
|
58
85
|
```
|
|
59
86
|
|
|
60
87
|
---
|
|
@@ -65,18 +92,18 @@ wilcocrypt.decryptFile('file.txt.enc', 'my-password', 'output.txt');
|
|
|
65
92
|
|
|
66
93
|
Encrypts a Buffer using password-based AES-256-GCM. The password is never stored; a random salt is generated for every encryption call.
|
|
67
94
|
|
|
68
|
-
| Parameter
|
|
69
|
-
|
|
70
|
-
| `plaindata
|
|
71
|
-
| `password`
|
|
72
|
-
| `gzip`
|
|
95
|
+
| Parameter | Type | Default | Description |
|
|
96
|
+
| ----------- | --------- | ------- | ------------------------------------------ |
|
|
97
|
+
| `plaindata` | `Buffer` | — | Raw data to encrypt |
|
|
98
|
+
| `password` | `string` | — | Password for key derivation (min. 6 chars) |
|
|
99
|
+
| `gzip` | `boolean` | `true` | Compress data before encryption |
|
|
73
100
|
|
|
74
101
|
**Returns:** `Buffer` — the encrypted payload in the [binary format](#binary-payload-format).
|
|
75
102
|
|
|
76
103
|
**Throws:** `WilcoCryptError` with code `WEAK_PASSWORD` if the password is too short.
|
|
77
104
|
|
|
78
105
|
```js
|
|
79
|
-
const encrypted = wilcocrypt.encryptData(Buffer.from(
|
|
106
|
+
const encrypted = wilcocrypt.encryptData(Buffer.from("secret"), "passw0rd");
|
|
80
107
|
```
|
|
81
108
|
|
|
82
109
|
---
|
|
@@ -85,25 +112,25 @@ const encrypted = wilcocrypt.encryptData(Buffer.from('secret'), 'passw0rd');
|
|
|
85
112
|
|
|
86
113
|
Decrypts a payload produced by `encryptData`. Validates the header and version before attempting decryption.
|
|
87
114
|
|
|
88
|
-
| Parameter | Type | Default | Description
|
|
89
|
-
|
|
90
|
-
| `encryptedBuffer` | `Buffer` | — | Payload from `encryptData`
|
|
91
|
-
| `password` | `string` | — | Password used during encryption
|
|
92
|
-
| `gzip` | `boolean` | `true` | Decompress after decryption
|
|
115
|
+
| Parameter | Type | Default | Description |
|
|
116
|
+
| ----------------- | --------- | ------- | ------------------------------- |
|
|
117
|
+
| `encryptedBuffer` | `Buffer` | — | Payload from `encryptData` |
|
|
118
|
+
| `password` | `string` | — | Password used during encryption |
|
|
119
|
+
| `gzip` | `boolean` | `true` | Decompress after decryption |
|
|
93
120
|
|
|
94
121
|
**Returns:** `Buffer` — the original plaintext data.
|
|
95
122
|
|
|
96
123
|
**Throws:**
|
|
97
124
|
|
|
98
|
-
| Code | Reason
|
|
99
|
-
|
|
100
|
-
| `WEAK_PASSWORD` | Password shorter than 6 characters
|
|
101
|
-
| `INVALID_HEADER` | Not a valid WilcoCrypt payload
|
|
125
|
+
| Code | Reason |
|
|
126
|
+
| ------------------- | ---------------------------------------------- |
|
|
127
|
+
| `WEAK_PASSWORD` | Password shorter than 6 characters |
|
|
128
|
+
| `INVALID_HEADER` | Not a valid WilcoCrypt payload |
|
|
102
129
|
| `VERSION_MISMATCH` | Payload was encrypted with a different version |
|
|
103
|
-
| `DECRYPTION_FAILED` | Wrong password, tampered or corrupt data
|
|
130
|
+
| `DECRYPTION_FAILED` | Wrong password, tampered or corrupt data |
|
|
104
131
|
|
|
105
132
|
```js
|
|
106
|
-
const plain = wilcocrypt.decryptData(encrypted,
|
|
133
|
+
const plain = wilcocrypt.decryptData(encrypted, "passw0rd");
|
|
107
134
|
```
|
|
108
135
|
|
|
109
136
|
---
|
|
@@ -112,16 +139,16 @@ const plain = wilcocrypt.decryptData(encrypted, 'passw0rd');
|
|
|
112
139
|
|
|
113
140
|
Reads a file, encrypts it, and writes the result to `<filePath>.enc`. Uses `encryptData` internally, so the entire file is loaded into memory. For large files, use [`encryptFileStream`](#encryptfilestream) instead.
|
|
114
141
|
|
|
115
|
-
| Parameter | Type | Default | Description
|
|
116
|
-
|
|
117
|
-
| `filePath` | `string` | — | Path to the source file
|
|
118
|
-
| `password` | `string` | — | Password for key derivation
|
|
119
|
-
| `gzip` | `boolean` | `true` | Compress before encryption
|
|
142
|
+
| Parameter | Type | Default | Description |
|
|
143
|
+
| ---------- | --------- | ------- | --------------------------- |
|
|
144
|
+
| `filePath` | `string` | — | Path to the source file |
|
|
145
|
+
| `password` | `string` | — | Password for key derivation |
|
|
146
|
+
| `gzip` | `boolean` | `true` | Compress before encryption |
|
|
120
147
|
|
|
121
148
|
**Returns:** `void`
|
|
122
149
|
|
|
123
150
|
```js
|
|
124
|
-
wilcocrypt.encryptFile(
|
|
151
|
+
wilcocrypt.encryptFile("document.pdf", "passw0rd");
|
|
125
152
|
// Creates document.pdf.enc
|
|
126
153
|
```
|
|
127
154
|
|
|
@@ -131,12 +158,12 @@ wilcocrypt.encryptFile('document.pdf', 'passw0rd');
|
|
|
131
158
|
|
|
132
159
|
Decrypts a `.enc` file. If `outputPath` is provided, the result is written to disk and `undefined` is returned. Otherwise the decrypted `Buffer` is returned.
|
|
133
160
|
|
|
134
|
-
| Parameter | Type | Default | Description
|
|
135
|
-
|
|
136
|
-
| `filePath` | `string` | — | Path to the `.enc` file
|
|
137
|
-
| `password` | `string` | — | Password used during encryption
|
|
138
|
-
| `outputPath` | `string` | `undefined` | Optional path to write decrypted output to
|
|
139
|
-
| `gzip` | `boolean` | `true` | Decompress after decryption
|
|
161
|
+
| Parameter | Type | Default | Description |
|
|
162
|
+
| ------------ | --------- | ----------- | ------------------------------------------ |
|
|
163
|
+
| `filePath` | `string` | — | Path to the `.enc` file |
|
|
164
|
+
| `password` | `string` | — | Password used during encryption |
|
|
165
|
+
| `outputPath` | `string` | `undefined` | Optional path to write decrypted output to |
|
|
166
|
+
| `gzip` | `boolean` | `true` | Decompress after decryption |
|
|
140
167
|
|
|
141
168
|
> The legacy 3-argument form `decryptFile(filePath, password, gzip)` is still fully supported, but will be deprecated in the next release.
|
|
142
169
|
|
|
@@ -146,10 +173,124 @@ Decrypts a `.enc` file. If `outputPath` is provided, the result is written to di
|
|
|
146
173
|
|
|
147
174
|
```js
|
|
148
175
|
// Return as Buffer
|
|
149
|
-
const buf = wilcocrypt.decryptFile(
|
|
176
|
+
const buf = wilcocrypt.decryptFile("document.pdf.enc", "passw0rd");
|
|
150
177
|
|
|
151
178
|
// Write directly to disk
|
|
152
|
-
wilcocrypt.decryptFile(
|
|
179
|
+
wilcocrypt.decryptFile("document.pdf.enc", "passw0rd", "document.pdf");
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
### `encryptDataAsync(plaindata, password, gzip?)`
|
|
185
|
+
|
|
186
|
+
Asynchronous version of `encryptData`.
|
|
187
|
+
|
|
188
|
+
Encrypts a Buffer using password-based AES-256-GCM. The password is never stored; a random salt is generated for every encryption call.
|
|
189
|
+
|
|
190
|
+
| Parameter | Type | Default | Description |
|
|
191
|
+
| ----------- | --------- | ------- | ------------------------------------------ |
|
|
192
|
+
| `plaindata` | `Buffer` | — | Raw data to encrypt |
|
|
193
|
+
| `password` | `string` | — | Password for key derivation (min. 6 chars) |
|
|
194
|
+
| `gzip` | `boolean` | `true` | Compress data before encryption |
|
|
195
|
+
|
|
196
|
+
**Returns:** `Promise<Buffer>` — the encrypted payload in the binary format.
|
|
197
|
+
|
|
198
|
+
**Throws:** `WilcoCryptError` with code `WEAK_PASSWORD` if the password is too short.
|
|
199
|
+
|
|
200
|
+
```js
|
|
201
|
+
const encrypted = await wilcocrypt.encryptDataAsync(
|
|
202
|
+
Buffer.from("secret"),
|
|
203
|
+
"passw0rd",
|
|
204
|
+
);
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
### `decryptDataAsync(encryptedBuffer, password, gzip?)`
|
|
210
|
+
|
|
211
|
+
Asynchronous version of `decryptData`.
|
|
212
|
+
|
|
213
|
+
Decrypts a payload produced by `encryptDataAsync` or `encryptData`. Validates the header and version before attempting decryption.
|
|
214
|
+
|
|
215
|
+
| Parameter | Type | Default | Description |
|
|
216
|
+
| ----------------- | --------- | ------- | ------------------------------- |
|
|
217
|
+
| `encryptedBuffer` | `Buffer` | — | Payload from `encryptData` |
|
|
218
|
+
| `password` | `string` | — | Password used during encryption |
|
|
219
|
+
| `gzip` | `boolean` | `true` | Decompress after decryption |
|
|
220
|
+
|
|
221
|
+
**Returns:** `Promise<Buffer>` — the original plaintext data.
|
|
222
|
+
|
|
223
|
+
**Throws:**
|
|
224
|
+
|
|
225
|
+
| Code | Reason |
|
|
226
|
+
| ------------------- | ---------------------------------------------- |
|
|
227
|
+
| `WEAK_PASSWORD` | Password shorter than 6 characters |
|
|
228
|
+
| `INVALID_HEADER` | Not a valid WilcoCrypt payload |
|
|
229
|
+
| `VERSION_MISMATCH` | Payload was encrypted with a different version |
|
|
230
|
+
| `DECRYPTION_FAILED` | Wrong password, tampered or corrupt data |
|
|
231
|
+
|
|
232
|
+
```js
|
|
233
|
+
const plain = await wilcocrypt.decryptDataAsync(
|
|
234
|
+
encrypted,
|
|
235
|
+
"passw0rd",
|
|
236
|
+
);
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
### `encryptFileAsync(filePath, password, gzip?)`
|
|
242
|
+
|
|
243
|
+
Asynchronous version of `encryptFile`.
|
|
244
|
+
|
|
245
|
+
Reads a file, encrypts it, and writes the result to `<filePath>.enc`.
|
|
246
|
+
|
|
247
|
+
| Parameter | Type | Default | Description |
|
|
248
|
+
| ---------- | --------- | ------- | --------------------------- |
|
|
249
|
+
| `filePath` | `string` | — | Path to the source file |
|
|
250
|
+
| `password` | `string` | — | Password for key derivation |
|
|
251
|
+
| `gzip` | `boolean` | `true` | Compress before encryption |
|
|
252
|
+
|
|
253
|
+
**Returns:** `Promise<void>`
|
|
254
|
+
|
|
255
|
+
```js
|
|
256
|
+
await wilcocrypt.encryptFileAsync(
|
|
257
|
+
"document.pdf",
|
|
258
|
+
"passw0rd",
|
|
259
|
+
);
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
### `decryptFileAsync(filePath, password, outputPath?, gzip?)`
|
|
265
|
+
|
|
266
|
+
Asynchronous version of `decryptFile`.
|
|
267
|
+
|
|
268
|
+
If `outputPath` is provided, the result is written to disk and `undefined` is returned. Otherwise the decrypted `Buffer` is returned.
|
|
269
|
+
|
|
270
|
+
| Parameter | Type | Default | Description |
|
|
271
|
+
| ------------ | --------- | ----------- | ------------------------------------------ |
|
|
272
|
+
| `filePath` | `string` | — | Path to the `.enc` file |
|
|
273
|
+
| `password` | `string` | — | Password used during encryption |
|
|
274
|
+
| `outputPath` | `string` | `undefined` | Optional path to write decrypted output to |
|
|
275
|
+
| `gzip` | `boolean` | `true` | Decompress after decryption |
|
|
276
|
+
|
|
277
|
+
**Returns:** `Promise<Buffer>` when no `outputPath` is given, `Promise<undefined>` otherwise.
|
|
278
|
+
|
|
279
|
+
**Throws:** Same error codes as `decryptFile`.
|
|
280
|
+
|
|
281
|
+
```js
|
|
282
|
+
// Return as Buffer
|
|
283
|
+
const buf = await wilcocrypt.decryptFileAsync(
|
|
284
|
+
"document.pdf.enc",
|
|
285
|
+
"passw0rd",
|
|
286
|
+
);
|
|
287
|
+
|
|
288
|
+
// Write directly to disk
|
|
289
|
+
await wilcocrypt.decryptFileAsync(
|
|
290
|
+
"document.pdf.enc",
|
|
291
|
+
"passw0rd",
|
|
292
|
+
"document.pdf",
|
|
293
|
+
);
|
|
153
294
|
```
|
|
154
295
|
|
|
155
296
|
---
|
|
@@ -158,17 +299,21 @@ wilcocrypt.decryptFile('document.pdf.enc', 'passw0rd', 'document.pdf');
|
|
|
158
299
|
|
|
159
300
|
Streaming equivalent of `encryptFile`. Reads from `inputPath` and writes to `outputPath` chunk by chunk — suitable for large files where loading everything into memory is impractical.
|
|
160
301
|
|
|
161
|
-
| Parameter | Type | Default | Description
|
|
162
|
-
|
|
163
|
-
| `inputPath` | `string` | — | Path to the source file
|
|
164
|
-
| `outputPath` | `string` | — | Path for the encrypted output
|
|
165
|
-
| `password` | `string` | — | Password for key derivation
|
|
166
|
-
| `gzip` | `boolean` | `true` | Compress before encryption
|
|
302
|
+
| Parameter | Type | Default | Description |
|
|
303
|
+
| ------------ | --------- | ------- | ----------------------------- |
|
|
304
|
+
| `inputPath` | `string` | — | Path to the source file |
|
|
305
|
+
| `outputPath` | `string` | — | Path for the encrypted output |
|
|
306
|
+
| `password` | `string` | — | Password for key derivation |
|
|
307
|
+
| `gzip` | `boolean` | `true` | Compress before encryption |
|
|
167
308
|
|
|
168
309
|
**Returns:** `Promise<void>`
|
|
169
310
|
|
|
170
311
|
```js
|
|
171
|
-
await wilcocrypt.encryptFileStream(
|
|
312
|
+
await wilcocrypt.encryptFileStream(
|
|
313
|
+
"bigfile.zip",
|
|
314
|
+
"bigfile.zip.enc",
|
|
315
|
+
"passw0rd",
|
|
316
|
+
);
|
|
172
317
|
```
|
|
173
318
|
|
|
174
319
|
---
|
|
@@ -177,19 +322,23 @@ await wilcocrypt.encryptFileStream('bigfile.zip', 'bigfile.zip.enc', 'passw0rd')
|
|
|
177
322
|
|
|
178
323
|
Streaming equivalent of `decryptFile`. Header and version are validated before the stream starts. If decryption fails at any point, the partially written output file is deleted automatically.
|
|
179
324
|
|
|
180
|
-
| Parameter | Type | Default | Description
|
|
181
|
-
|
|
182
|
-
| `inputPath` | `string` | — | Path to the `.enc` file
|
|
183
|
-
| `outputPath` | `string` | — | Path to write decrypted output to
|
|
184
|
-
| `password` | `string` | — | Password used during encryption
|
|
185
|
-
| `gzip` | `boolean` | `true` | Decompress after decryption
|
|
325
|
+
| Parameter | Type | Default | Description |
|
|
326
|
+
| ------------ | --------- | ------- | --------------------------------- |
|
|
327
|
+
| `inputPath` | `string` | — | Path to the `.enc` file |
|
|
328
|
+
| `outputPath` | `string` | — | Path to write decrypted output to |
|
|
329
|
+
| `password` | `string` | — | Password used during encryption |
|
|
330
|
+
| `gzip` | `boolean` | `true` | Decompress after decryption |
|
|
186
331
|
|
|
187
332
|
**Returns:** `Promise<void>`
|
|
188
333
|
|
|
189
334
|
**Throws:** Same error codes as `decryptData`, plus automatic cleanup of `outputPath` on failure.
|
|
190
335
|
|
|
191
336
|
```js
|
|
192
|
-
await wilcocrypt.decryptFileStream(
|
|
337
|
+
await wilcocrypt.decryptFileStream(
|
|
338
|
+
"bigfile.zip.enc",
|
|
339
|
+
"bigfile.zip",
|
|
340
|
+
"passw0rd",
|
|
341
|
+
);
|
|
193
342
|
```
|
|
194
343
|
|
|
195
344
|
---
|
|
@@ -198,17 +347,17 @@ await wilcocrypt.decryptFileStream('bigfile.zip.enc', 'bigfile.zip', 'passw0rd')
|
|
|
198
347
|
|
|
199
348
|
The `wilcocrypt._` namespace exposes internal helpers. These are not intended for normal use but are part of the public surface for advanced use cases and testing.
|
|
200
349
|
|
|
201
|
-
| Member
|
|
202
|
-
|
|
203
|
-
| `_.VERSION`
|
|
204
|
-
| `_.MIN_PASSWORD_LENGTH`
|
|
205
|
-
| `_.HEADER`
|
|
206
|
-
| `_.WilcoCryptError`
|
|
207
|
-
| `_.assertKeyAndIv(key, iv)`
|
|
208
|
-
| `_.assertPassword(password)`
|
|
209
|
-
| `_.constantTimeEqual(a, b)`
|
|
210
|
-
| `_.encryptData(plainData, key, iv)`
|
|
211
|
-
| `_.decryptData(cipherBuffer, authTagBuffer, key, iv)` | `function` | Raw AES-256-GCM decryption, returns `Buffer`
|
|
350
|
+
| Member | Type | Description |
|
|
351
|
+
| ----------------------------------------------------- | ---------- | ------------------------------------------------------------- |
|
|
352
|
+
| `_.VERSION` | `string` | Current version string, embedded in every payload |
|
|
353
|
+
| `_.MIN_PASSWORD_LENGTH` | `number` | Minimum accepted password length (6) |
|
|
354
|
+
| `_.HEADER` | `Buffer` | 10-byte magic bytes identifying a WilcoCrypt payload |
|
|
355
|
+
| `_.WilcoCryptError` | `class` | The error class (also importable from TypeScript types) |
|
|
356
|
+
| `_.assertKeyAndIv(key, iv)` | `function` | Throws if key or IV are not valid Buffers of the right length |
|
|
357
|
+
| `_.assertPassword(password)` | `function` | Throws `WEAK_PASSWORD` if password is too short |
|
|
358
|
+
| `_.constantTimeEqual(a, b)` | `function` | Constant-time Buffer comparison, returns `boolean` |
|
|
359
|
+
| `_.encryptData(plainData, key, iv)` | `function` | Raw AES-256-GCM encryption, returns `{ ciphertext, authTag }` |
|
|
360
|
+
| `_.decryptData(cipherBuffer, authTagBuffer, key, iv)` | `function` | Raw AES-256-GCM decryption, returns `Buffer` |
|
|
212
361
|
|
|
213
362
|
---
|
|
214
363
|
|
|
@@ -223,14 +372,14 @@ wilcocrypt --help
|
|
|
223
372
|
|
|
224
373
|
### Options
|
|
225
374
|
|
|
226
|
-
| Flag
|
|
227
|
-
|
|
228
|
-
| `-e, --encrypt <file>`
|
|
229
|
-
| `-d, --decrypt <file>`
|
|
230
|
-
| `-o, --output <file>`
|
|
231
|
-
| `--stdout`
|
|
232
|
-
| `--version`
|
|
233
|
-
| `-h, --help`
|
|
375
|
+
| Flag | Description |
|
|
376
|
+
| ---------------------- | ----------------------------------------------------- |
|
|
377
|
+
| `-e, --encrypt <file>` | Encrypt the given file, writes `<file>.enc` |
|
|
378
|
+
| `-d, --decrypt <file>` | Decrypt the given `.enc` file |
|
|
379
|
+
| `-o, --output <file>` | Write decrypted output to `<file>` instead of stdout |
|
|
380
|
+
| `--stdout` | Explicitly write decrypted output to stdout (default) |
|
|
381
|
+
| `--version` | Show WilcoCrypt version |
|
|
382
|
+
| `-h, --help` | Show help |
|
|
234
383
|
|
|
235
384
|
Only one of `-e` or `-d` may be used at a time. The `--output` and `--stdout` flags are mutually exclusive. `--output` is only valid with `-d`.
|
|
236
385
|
|
|
@@ -256,7 +405,7 @@ Passwords are entered interactively with character masking (`*`). The CLI requir
|
|
|
256
405
|
|
|
257
406
|
## Binary Payload Format
|
|
258
407
|
|
|
259
|
-
Every payload produced
|
|
408
|
+
Every payload produced in WilcoCrypt v2.2.x has the following binary layout:
|
|
260
409
|
|
|
261
410
|
```
|
|
262
411
|
[ HEADER ] 10 bytes — magic bytes: 23 9 12 3 15 3 18 25 16 20
|
|
@@ -278,14 +427,14 @@ The auth tag is placed at the end to allow the streaming API to append it after
|
|
|
278
427
|
All errors thrown by WilcoCrypt are instances of `WilcoCryptError`, which extends `Error` with a `code` property.
|
|
279
428
|
|
|
280
429
|
```js
|
|
281
|
-
import wilcocrypt from
|
|
430
|
+
import wilcocrypt from "wilcocrypt";
|
|
282
431
|
const { WilcoCryptError } = wilcocrypt._;
|
|
283
432
|
|
|
284
433
|
try {
|
|
285
|
-
wilcocrypt.decryptData(payload,
|
|
434
|
+
wilcocrypt.decryptData(payload, "wrong-password");
|
|
286
435
|
} catch (err) {
|
|
287
436
|
if (err instanceof WilcoCryptError) {
|
|
288
|
-
console.error(err.code);
|
|
437
|
+
console.error(err.code); // e.g. DECRYPTION_FAILED
|
|
289
438
|
console.error(err.message); // human-readable
|
|
290
439
|
}
|
|
291
440
|
}
|
|
@@ -293,16 +442,16 @@ try {
|
|
|
293
442
|
|
|
294
443
|
### Error Codes
|
|
295
444
|
|
|
296
|
-
| Code
|
|
297
|
-
|
|
298
|
-
| `WEAK_PASSWORD`
|
|
299
|
-
| `INVALID_HEADER`
|
|
300
|
-
| `VERSION_MISMATCH`
|
|
301
|
-
| `DECRYPTION_FAILED`
|
|
302
|
-
| `INVALID_FILE_EXTENSION
|
|
303
|
-
| `INVALID_KEY`
|
|
304
|
-
| `INVALID_IV`
|
|
305
|
-
| `NO_TTY`
|
|
445
|
+
| Code | Thrown by | Cause |
|
|
446
|
+
| ------------------------ | --------------------------------------------- | ------------------------------------------------------ |
|
|
447
|
+
| `WEAK_PASSWORD` | All public methods | Password shorter than 6 characters |
|
|
448
|
+
| `INVALID_HEADER` | `decryptData`, `decryptFile`, stream variants | Payload does not start with the WilcoCrypt magic bytes |
|
|
449
|
+
| `VERSION_MISMATCH` | `decryptData`, `decryptFile`, stream variants | Payload version does not match current version |
|
|
450
|
+
| `DECRYPTION_FAILED` | `decryptData`, `decryptFile`, stream variants | Wrong password, tampered data, or corruption |
|
|
451
|
+
| `INVALID_FILE_EXTENSION` | `decryptFile` | File path does not end with `.enc` |
|
|
452
|
+
| `INVALID_KEY` | `_.assertKeyAndIv` | Key is not a 32-byte Buffer |
|
|
453
|
+
| `INVALID_IV` | `_.assertKeyAndIv` | IV is not a 12-byte Buffer |
|
|
454
|
+
| `NO_TTY` | CLI password prompt | stdin is not a TTY |
|
|
306
455
|
|
|
307
456
|
---
|
|
308
457
|
|
|
@@ -311,17 +460,60 @@ try {
|
|
|
311
460
|
WilcoCrypt ships with `wilcocrypt.d.ts`. No `@types` package needed.
|
|
312
461
|
|
|
313
462
|
```ts
|
|
314
|
-
import wilcocrypt, {
|
|
315
|
-
|
|
316
|
-
|
|
463
|
+
import wilcocrypt, {
|
|
464
|
+
WilcoCryptError,
|
|
465
|
+
} from "wilcocrypt";
|
|
466
|
+
|
|
467
|
+
const encrypted: Buffer =
|
|
468
|
+
wilcocrypt.encryptData(
|
|
469
|
+
Buffer.from("hi"),
|
|
470
|
+
"passw0rd",
|
|
471
|
+
);
|
|
472
|
+
|
|
473
|
+
const encryptedAsync: Buffer =
|
|
474
|
+
await wilcocrypt.encryptDataAsync(
|
|
475
|
+
Buffer.from("hi"),
|
|
476
|
+
"passw0rd",
|
|
477
|
+
);
|
|
317
478
|
|
|
318
479
|
// decryptFile overloads
|
|
319
|
-
const buf: Buffer =
|
|
320
|
-
wilcocrypt.decryptFile(
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
480
|
+
const buf: Buffer =
|
|
481
|
+
wilcocrypt.decryptFile(
|
|
482
|
+
"file.enc",
|
|
483
|
+
"passw0rd",
|
|
484
|
+
);
|
|
485
|
+
|
|
486
|
+
wilcocrypt.decryptFile(
|
|
487
|
+
"file.enc",
|
|
488
|
+
"passw0rd",
|
|
489
|
+
"output.txt",
|
|
490
|
+
);
|
|
491
|
+
|
|
492
|
+
// async overloads
|
|
493
|
+
const asyncBuf: Buffer =
|
|
494
|
+
await wilcocrypt.decryptFileAsync(
|
|
495
|
+
"file.enc",
|
|
496
|
+
"passw0rd",
|
|
497
|
+
);
|
|
498
|
+
|
|
499
|
+
await wilcocrypt.decryptFileAsync(
|
|
500
|
+
"file.enc",
|
|
501
|
+
"passw0rd",
|
|
502
|
+
"output.txt",
|
|
503
|
+
);
|
|
504
|
+
|
|
505
|
+
// streams
|
|
506
|
+
await wilcocrypt.encryptFileStream(
|
|
507
|
+
"in.txt",
|
|
508
|
+
"in.txt.enc",
|
|
509
|
+
"passw0rd",
|
|
510
|
+
);
|
|
511
|
+
|
|
512
|
+
await wilcocrypt.decryptFileStream(
|
|
513
|
+
"in.txt.enc",
|
|
514
|
+
"out.txt",
|
|
515
|
+
"passw0rd",
|
|
516
|
+
);
|
|
325
517
|
```
|
|
326
518
|
|
|
327
519
|
---
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# WilcoCrypt
|
|
2
2
|
|
|
3
|
-
[](https://github.com/prettier/prettier)
|
|
4
4
|
|
|
5
5
|
> **The `master` branch may be unstable during active development.**
|
|
6
6
|
> For production use, always install from [npm](https://www.npmjs.com/package/wilcocrypt) or use a tagged [GitHub Release](https://github.com/computer-wilco/wilcocrypt/releases).
|
|
@@ -14,10 +14,11 @@ A simple, modern Node.js encryption library and CLI tool. AES-256-GCM, password-
|
|
|
14
14
|
- AES-256-GCM authenticated encryption
|
|
15
15
|
- scrypt key derivation with a random salt per encryption
|
|
16
16
|
- Optional gzip compression before encryption
|
|
17
|
+
- Synchronous and asynchronous APIs
|
|
17
18
|
- Streaming API for large files (`encryptFileStream` / `decryptFileStream`)
|
|
18
19
|
- CLI with interactive password prompt
|
|
19
|
-
- TypeScript
|
|
20
|
-
-
|
|
20
|
+
- Comprehensive TypeScript definitions with full JSDoc support
|
|
21
|
+
- Prettier code formatting
|
|
21
22
|
|
|
22
23
|
---
|
|
23
24
|
|
|
@@ -34,24 +35,24 @@ Requires Node.js 18 or later.
|
|
|
34
35
|
## Quick Start
|
|
35
36
|
|
|
36
37
|
```js
|
|
37
|
-
import wilcocrypt from
|
|
38
|
+
import wilcocrypt from "wilcocrypt";
|
|
38
39
|
|
|
39
40
|
// Encrypt / decrypt a Buffer
|
|
40
|
-
const encrypted = wilcocrypt.encryptData(Buffer.from(
|
|
41
|
-
const decrypted = wilcocrypt.decryptData(encrypted,
|
|
41
|
+
const encrypted = wilcocrypt.encryptData(Buffer.from("Hello!"), "my-password");
|
|
42
|
+
const decrypted = wilcocrypt.decryptData(encrypted, "my-password");
|
|
42
43
|
|
|
43
44
|
// Encrypt a file → writes file.txt.enc
|
|
44
|
-
wilcocrypt.encryptFile(
|
|
45
|
+
wilcocrypt.encryptFile("file.txt", "my-password");
|
|
45
46
|
|
|
46
47
|
// Decrypt to Buffer
|
|
47
|
-
const buf = wilcocrypt.decryptFile(
|
|
48
|
+
const buf = wilcocrypt.decryptFile("file.txt.enc", "my-password");
|
|
48
49
|
|
|
49
50
|
// Decrypt directly to disk
|
|
50
|
-
wilcocrypt.decryptFile(
|
|
51
|
+
wilcocrypt.decryptFile("file.txt.enc", "my-password", "output.txt");
|
|
51
52
|
|
|
52
53
|
// Stream API (memory-efficient for large files)
|
|
53
|
-
await wilcocrypt.encryptFileStream(
|
|
54
|
-
await wilcocrypt.decryptFileStream(
|
|
54
|
+
await wilcocrypt.encryptFileStream("big.zip", "big.zip.enc", "my-password");
|
|
55
|
+
await wilcocrypt.decryptFileStream("big.zip.enc", "big.zip", "my-password");
|
|
55
56
|
```
|
|
56
57
|
|
|
57
58
|
---
|
|
@@ -91,14 +92,14 @@ The auth tag is appended at the end for streaming compatibility. See [DOCS.md](.
|
|
|
91
92
|
All errors are instances of `WilcoCryptError` with a machine-readable `code` property.
|
|
92
93
|
|
|
93
94
|
```js
|
|
94
|
-
import wilcocrypt from
|
|
95
|
+
import wilcocrypt from "wilcocrypt";
|
|
95
96
|
const { WilcoCryptError } = wilcocrypt._;
|
|
96
97
|
|
|
97
98
|
try {
|
|
98
|
-
wilcocrypt.decryptData(payload,
|
|
99
|
+
wilcocrypt.decryptData(payload, "wrong");
|
|
99
100
|
} catch (err) {
|
|
100
101
|
if (err instanceof WilcoCryptError) {
|
|
101
|
-
console.error(err.code);
|
|
102
|
+
console.error(err.code); // e.g. DECRYPTION_FAILED
|
|
102
103
|
console.error(err.message);
|
|
103
104
|
}
|
|
104
105
|
}
|
package/SECURITY.md
CHANGED
|
@@ -6,11 +6,12 @@ The following versions of WilcoCrypt are currently supported with security updat
|
|
|
6
6
|
|
|
7
7
|
| Version | Supported |
|
|
8
8
|
| ------- | ------------------ |
|
|
9
|
-
| 2.
|
|
9
|
+
| 2.2.x | :white_check_mark: |
|
|
10
|
+
| 2.1.x | :x: |
|
|
10
11
|
| 2.0.x | :x: |
|
|
11
12
|
| 1.x | :x: |
|
|
12
13
|
|
|
13
|
-
Only the latest minor version in the 2.x range receives
|
|
14
|
+
Only the latest minor version in the 2.x range receives updates. All the versions below that are not supported.
|
|
14
15
|
|
|
15
16
|
---
|
|
16
17
|
|
|
@@ -24,16 +25,15 @@ If you discover a security vulnerability in WilcoCrypt, please report it respons
|
|
|
24
25
|
|
|
25
26
|
Please include:
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
- A clear description of the issue
|
|
29
|
+
- Steps to reproduce (if possible)
|
|
30
|
+
- Impact assessment (what can go wrong)
|
|
30
31
|
|
|
31
32
|
### What to expect
|
|
32
33
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
* A patched version will be released and documented
|
|
34
|
+
- I will investigate and confirm the issue
|
|
35
|
+
- If accepted, a fix will be developed as soon as possible
|
|
36
|
+
- A patched version will be released and documented
|
|
37
37
|
|
|
38
38
|
### Responsible disclosure
|
|
39
39
|
|
|
@@ -43,6 +43,6 @@ Please do **not** publicly disclose the vulnerability until a fix has been relea
|
|
|
43
43
|
|
|
44
44
|
## Notes
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
- WilcoCrypt is designed with strong cryptographic defaults, but misuse (e.g. weak passwords) can still lead to insecure outcomes
|
|
47
|
+
- Always use strong, unique passwords
|
|
48
|
+
- Security is a shared responsibility between the library and its users
|