aes256-async 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Jesus Graterol
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,118 @@
1
+ # AES-256 Async
2
+
3
+ The `aes256-async` package allows developers to easily encrypt and decrypt data by making use of the [AES-256](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) specification. It exposes syncrhonous and asynchronous functions to avoid blocking the main thread. Moreover, the secret can be of any size because it is hashed using the [Secure Hash Algorithm 2 (SHA-256)](https://en.wikipedia.org/wiki/SHA-2).
4
+
5
+
6
+
7
+
8
+
9
+ </br>
10
+
11
+ ## Getting Started
12
+
13
+ Install the package:
14
+ ```bash
15
+ npm install -S aes256-async
16
+ ```
17
+
18
+
19
+ ## Usage
20
+
21
+ Encrypt and decrypt data asynchronously:
22
+
23
+ ```typescript
24
+ import { encrypt, decrypt } from 'aes256-async';
25
+
26
+ const secret = 'My.$ecreT';
27
+
28
+ await encrypt(secret, 'Hello world!')
29
+ // OrGfQ/91d7p/1BN6Q07Jly5ZK0/7pyczjk5vgw==
30
+
31
+ await decrypt(secret, 'OrGfQ/91d7p/1BN6Q07Jly5ZK0/7pyczjk5vgw==')
32
+ // 'Hello world!'
33
+ ```
34
+
35
+
36
+ Encrypt and decrypt data synchronously (blocking the main thread):
37
+
38
+ ```typescript
39
+ import { encryptSync, decryptSync } from 'aes256-async';
40
+
41
+ const secret = 'My.$ecreT';
42
+
43
+ encryptSync(secret, 'Hello world!')
44
+ // OrGfQ/91d7p/1BN6Q07Jly5ZK0/7pyczjk5vgw==
45
+
46
+ decryptSync(secret, 'OrGfQ/91d7p/1BN6Q07Jly5ZK0/7pyczjk5vgw==')
47
+ // 'Hello world!'
48
+ ```
49
+
50
+
51
+
52
+
53
+
54
+ <br/>
55
+
56
+ ## Built With
57
+
58
+ - TypeScript
59
+
60
+
61
+
62
+
63
+
64
+ <br/>
65
+
66
+ ## Acknowledgements
67
+
68
+ - [JamesMGreene/node-aes256](https://github.com/JamesMGreene/node-aes256)
69
+
70
+
71
+
72
+
73
+ <br/>
74
+
75
+ ## Running the Tests
76
+
77
+ ```bash
78
+ # integration tests
79
+ npm run test:integration
80
+
81
+ # unit tests
82
+ npm run test:unit
83
+ ```
84
+
85
+
86
+
87
+
88
+
89
+ <br/>
90
+
91
+ ## License
92
+
93
+ [MIT](https://choosealicense.com/licenses/mit/)
94
+
95
+
96
+
97
+
98
+
99
+ <br/>
100
+
101
+ ## Deployment
102
+
103
+ Install dependencies:
104
+ ```bash
105
+ npm install
106
+ ```
107
+
108
+
109
+ Build the library:
110
+ ```bash
111
+ npm start
112
+ ```
113
+
114
+
115
+ Publish to `npm`:
116
+ ```bash
117
+ npm publish
118
+ ```
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Decrypts an encrypted message back to readable text.
3
+ * @param secret
4
+ * @param encryptedData
5
+ * @returns Promise<string>
6
+ * @throws
7
+ * - INVALID_OR_EMPTY_DATA: if the data is not a string or is an empty string.
8
+ * - INVALID_SECRET: if the secret is not a string or is an empty string.
9
+ * - INVALID_ENCRYPTED_DATA: if the encrypted data decrypts to an invalid or empty string.
10
+ * - WRONG_SECRET: if the data cannot be decrypted.
11
+ */
12
+ declare const decrypt: (secret: string, encryptedData: string) => Promise<string>;
13
+ /**
14
+ * Encrypts a message to a piece of text that cannot be read unless it is decrypted with the secret
15
+ * that was used to encrypt it.
16
+ * @param secret
17
+ * @param data
18
+ * @returns Promise<string>
19
+ * @throws
20
+ * - INVALID_OR_EMPTY_DATA: if the data is not a string or is an empty string.
21
+ * - INVALID_SECRET: if the secret is not a string or is an empty string.
22
+ * - CORRUPTED_DATA: if the decrypted data does not match the original data.
23
+ * - WRONG_SECRET: if the data cannot be decrypted.
24
+ */
25
+ declare const encrypt: (secret: string, data: string) => Promise<string>;
26
+ /**
27
+ * Decrypts an encrypted message back to readable text.
28
+ * @param secret
29
+ * @param encryptedData
30
+ * @returns string
31
+ * @throws
32
+ * - INVALID_OR_EMPTY_DATA: if the data is not a string or is an empty string.
33
+ * - INVALID_SECRET: if the secret is not a string or is an empty string.
34
+ * - INVALID_ENCRYPTED_DATA: if the encrypted data decrypts to an invalid or empty string.
35
+ * - WRONG_SECRET: if the data cannot be decrypted.
36
+ */
37
+ declare const decryptSync: (secret: string, encryptedData: string) => string;
38
+ /**
39
+ * Encrypts a message to a piece of text that cannot be read unless it is decrypted with the secret
40
+ * that was used to encrypt it.
41
+ * @param secret
42
+ * @param data
43
+ * @returns string
44
+ * @throws
45
+ * - INVALID_OR_EMPTY_DATA: if the data is not a string or is an empty string.
46
+ * - INVALID_SECRET: if the secret is not a string or is an empty string.
47
+ * - CORRUPTED_DATA: if the decrypted data does not match the original data.
48
+ * - WRONG_SECRET: if the data cannot be decrypted.
49
+ */
50
+ declare const encryptSync: (secret: string, data: string) => string;
51
+ export { decrypt, encrypt, decryptSync, encryptSync, };
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ import{Buffer}from"node:buffer";import{decryptData,encryptData,decryptDataSync,encryptDataSync}from"./utils/index.js";import{validateInput,validateEncryptedBuffer,validateDecryptedData,validateEncryptionResult}from"./validations/index.js";const decrypt=async(t,a)=>{validateInput(t,a);const e=Buffer.from(a,"base64");validateEncryptedBuffer(e);const r=await decryptData(t,e);return validateDecryptedData(r),r},encrypt=async(t,a)=>{validateInput(t,a);const e=await encryptData(t,a);return validateEncryptionResult(a,await decrypt(t,e)),e},decryptSync=(t,a)=>{validateInput(t,a);const e=Buffer.from(a,"base64");validateEncryptedBuffer(e);const r=decryptDataSync(t,e);return validateDecryptedData(r),r},encryptSync=(t,a)=>{validateInput(t,a);const e=encryptDataSync(t,a);return validateEncryptionResult(a,decryptSync(t,e)),e};export{decrypt,encrypt,decryptSync,encryptSync};
@@ -0,0 +1,11 @@
1
+ declare const CIPHER_ALGORITHM = "aes-256-ctr";
2
+ declare const HASHING_ALGORITHM = "sha256";
3
+ /**
4
+ * Illegal Character
5
+ * Many web pages and other document formats use UTF-8. This is the default character encoding.
6
+ * When decoding a Buffer into a string that does not exclusively contain valid UTF-8 data, the
7
+ * Unicode replacement character U+FFFD � will be used to represent those errors.
8
+ * https://nodejs.org/docs/latest/api/buffer.html#buffers-and-character-encodings
9
+ */
10
+ declare const ILLEGAL_CHARACTER = "\uFFFD";
11
+ export { CIPHER_ALGORITHM, HASHING_ALGORITHM, ILLEGAL_CHARACTER, };
@@ -0,0 +1 @@
1
+ const CIPHER_ALGORITHM="aes-256-ctr",HASHING_ALGORITHM="sha256",ILLEGAL_CHARACTER="�";export{CIPHER_ALGORITHM,HASHING_ALGORITHM,ILLEGAL_CHARACTER};
@@ -0,0 +1,5 @@
1
+ type IErrors = 'INVALID_OR_EMPTY_DATA' | 'INVALID_SECRET' | 'INVALID_ENCRYPTED_DATA' | 'WRONG_SECRET' | 'CORRUPTED_DATA';
2
+ declare const ERRORS: {
3
+ [key in IErrors]: IErrors;
4
+ };
5
+ export { ERRORS, };
@@ -0,0 +1 @@
1
+ const ERRORS={INVALID_OR_EMPTY_DATA:"INVALID_OR_EMPTY_DATA",INVALID_SECRET:"INVALID_SECRET",INVALID_ENCRYPTED_DATA:"INVALID_ENCRYPTED_DATA",WRONG_SECRET:"WRONG_SECRET",CORRUPTED_DATA:"CORRUPTED_DATA"};export{ERRORS};
@@ -0,0 +1,42 @@
1
+ import { Buffer } from 'node:buffer';
2
+ /**
3
+ * Hashes the provided secret using the SHA-256 algorithm.
4
+ * @param secret
5
+ * @returns Promise<Buffer>
6
+ */
7
+ declare const __hashSecret: (secret: string) => Promise<Buffer>;
8
+ /**
9
+ * Hashes the provided secret using the SHA-256 algorithm.
10
+ * @param secret
11
+ * @returns Buffer
12
+ */
13
+ declare const __hashSecretSync: (secret: string) => Buffer;
14
+ /**
15
+ * Creates the cipher with random initialization vectors and returns the encrypted data.
16
+ * @param secret
17
+ * @param data
18
+ * @returns Promise<string>
19
+ */
20
+ declare const encryptData: (secret: string, data: string) => Promise<string>;
21
+ /**
22
+ * Creates the cipher with random initialization vectors and returns the encrypted data.
23
+ * @param secret
24
+ * @param data
25
+ * @returns string
26
+ */
27
+ declare const encryptDataSync: (secret: string, data: string) => string;
28
+ /**
29
+ * Creates the decipher and returns the result of the decryption.
30
+ * @param secret
31
+ * @param encryptedData
32
+ * @returns Promise<string>
33
+ */
34
+ declare const decryptData: (secret: string, encryptedData: Buffer) => Promise<string>;
35
+ /**
36
+ * Creates the decipher and returns the result of the decryption.
37
+ * @param secret
38
+ * @param encryptedData
39
+ * @returns string
40
+ */
41
+ declare const decryptDataSync: (secret: string, encryptedData: Buffer) => string;
42
+ export { __hashSecret, __hashSecretSync, encryptData, encryptDataSync, decryptData, decryptDataSync, };
@@ -0,0 +1 @@
1
+ import{Buffer}from"node:buffer";import crypto from"node:crypto";import{CIPHER_ALGORITHM,HASHING_ALGORITHM}from"../shared/constants.js";const __hashSecret=r=>new Promise(((t,e)=>{const a=crypto.createHash(HASHING_ALGORITHM);a.on("readable",(()=>{const r=a.read();r&&t(r)})),a.on("error",(r=>e(r))),a.write(r),a.end()})),__hashSecretSync=r=>{const t=crypto.createHash(HASHING_ALGORITHM);return t.update(r),t.digest()},encryptData=async(r,t)=>{const e=crypto.randomBytes(16),a=crypto.createCipheriv(CIPHER_ALGORITHM,await __hashSecret(r),e),c=Buffer.from(t),n=a.update(c);return Buffer.concat([e,n,a.final()]).toString("base64")},encryptDataSync=(r,t)=>{const e=crypto.randomBytes(16),a=crypto.createCipheriv(CIPHER_ALGORITHM,__hashSecretSync(r),e),c=Buffer.from(t),n=a.update(c);return Buffer.concat([e,n,a.final()]).toString("base64")},decryptData=async(r,t)=>{const e=t.subarray(0,16),a=await __hashSecret(r),c=crypto.createDecipheriv(CIPHER_ALGORITHM,a,e),n=t.subarray(16);return Buffer.concat([c.update(n),c.final()]).toString()},decryptDataSync=(r,t)=>{const e=t.subarray(0,16),a=crypto.createDecipheriv(CIPHER_ALGORITHM,__hashSecretSync(r),e),c=t.subarray(16);return Buffer.concat([a.update(c),a.final()]).toString()};export{__hashSecret,__hashSecretSync,encryptData,encryptDataSync,decryptData,decryptDataSync};
@@ -0,0 +1,35 @@
1
+ import { Buffer } from 'node:buffer';
2
+ /**
3
+ * Ensures the data and the secret are valid strings.
4
+ * @param secret
5
+ * @param data
6
+ * @throws
7
+ * - INVALID_OR_EMPTY_DATA: if the data is not a string or is an empty string.
8
+ * - INVALID_SECRET: if the secret is not a string or is an empty string.
9
+ */
10
+ declare const validateInput: (secret: string, data: string) => void;
11
+ /**
12
+ * Ensures the encrypted data is a valid string.
13
+ * @param input
14
+ * @throws
15
+ * - INVALID_ENCRYPTED_DATA: if the encrypted data decrypts to an invalid or empty string.
16
+ */
17
+ declare const validateEncryptedBuffer: (input: Buffer) => void;
18
+ /**
19
+ * Ensures the decrypted data is valid. So far, whenever an incorrect secret is provided, Node.js
20
+ * returns a string containing characters like �.
21
+ * @param data
22
+ * @throws
23
+ * - WRONG_SECRET: if the data cannot be decrypted.
24
+ */
25
+ declare const validateDecryptedData: (data: string) => void;
26
+ /**
27
+ * Compares the original data with the decrypted data to ensure the data was and can be decrypted
28
+ * correctly in the future.
29
+ * @param data
30
+ * @param decryptedData
31
+ * @throws
32
+ * - CORRUPTED_DATA: if the decrypted data does not match the original data.
33
+ */
34
+ declare const validateEncryptionResult: (data: string, decryptedData: string) => void;
35
+ export { validateInput, validateEncryptedBuffer, validateDecryptedData, validateEncryptionResult, };
@@ -0,0 +1 @@
1
+ import{encodeError}from"error-message-utils";import{ILLEGAL_CHARACTER}from"../shared/constants.js";import{ERRORS}from"../shared/errors.js";const __validateSecret=e=>{if("string"!=typeof e||0===e.length)throw new Error(encodeError("The provided secret is invalid, please make sure to provide a non-empty string.",ERRORS.INVALID_SECRET))},__validateData=e=>{if("string"!=typeof e||0===e.length||e.includes(ILLEGAL_CHARACTER))throw new Error(encodeError("The provided data is invalid, please make sure to provide a non-empty string that only contains UTF-8 character encoding.",ERRORS.INVALID_OR_EMPTY_DATA))},validateInput=(e,r)=>{__validateSecret(e),__validateData(r)},validateEncryptedBuffer=e=>{if(e.length<17)throw new Error(encodeError("The provided encrypted data must decrypt to a non-empty string.",ERRORS.INVALID_ENCRYPTED_DATA))},validateDecryptedData=e=>{if("string"!=typeof e||0===e.length||e.includes(ILLEGAL_CHARACTER))throw new Error(encodeError("Failed to decrypt the data with the provided secret.",ERRORS.WRONG_SECRET))},validateEncryptionResult=(e,r)=>{if(e!==r)throw new Error(encodeError("The data could not be decrypted correctly.",ERRORS.CORRUPTED_DATA))};export{validateInput,validateEncryptedBuffer,validateDecryptedData,validateEncryptionResult};
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "aes256-async",
3
+ "version": "1.0.0",
4
+ "description": "The aes256-async package allows developers to easily encrypt and decrypt data by making use of the AES-256 specification. It exposes syncrhonous and asynchronous functions to avoid blocking the main thread. Moreover, the secret can be of any size because it is hashed using the Secure Hash Algorithm 2 (SHA-256).",
5
+ "private": false,
6
+ "type": "module",
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "scripts": {
10
+ "start": "ts-lib-builder --tsconfig=tsconfig.build.json",
11
+ "test": "echo \"Error: tests are executed with npm run test:(e2e|integration|unit|bench)\" && exit 1",
12
+ "test:e2e": "vitest run --config=vitest.test-e2e.config.ts",
13
+ "test:integration": "vitest run --config vitest.test-integration.config.ts",
14
+ "test:unit": "vitest run --config vitest.test-unit.config.ts",
15
+ "test:bench": "vitest bench",
16
+ "watch-test:e2e": "vitest --config=vitest.test-e2e.config.ts",
17
+ "watch-test:integration": "vitest --config vitest.test-integration.config.ts",
18
+ "watch-test:unit": "vitest --config vitest.test-unit.config.ts"
19
+ },
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/jesusgraterol/aes256-async.git"
23
+ },
24
+ "keywords": [
25
+ "encryption",
26
+ "security",
27
+ "aes-256",
28
+ "sha-256",
29
+ "web",
30
+ "utilities",
31
+ "privacy"
32
+ ],
33
+ "author": "Jesus Graterol",
34
+ "license": "MIT",
35
+ "bugs": {
36
+ "url": "https://github.com/jesusgraterol/aes256-async/issues"
37
+ },
38
+ "homepage": "https://github.com/jesusgraterol/aes256-async#readme",
39
+ "devDependencies": {
40
+ "@types/node": "^22.10.5",
41
+ "@typescript-eslint/eslint-plugin": "^7.18.0",
42
+ "@typescript-eslint/parser": "^7.18.0",
43
+ "eslint-config-airbnb-typescript": "^18.0.0",
44
+ "ts-lib-builder": "^1.0.5",
45
+ "typescript": "^5.7.3",
46
+ "vitest": "^2.1.8"
47
+ },
48
+ "dependencies": {
49
+ "error-message-utils": "^1.1.2"
50
+ }
51
+ }