@vvlad1973/crypto 2.1.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/.hintrc +15 -0
- package/.vscode/launch.json +20 -0
- package/CLAUDE.md +90 -0
- package/LICENSE +19 -0
- package/README.md +253 -0
- package/dist/__tests__/crypto.test.d.ts +1 -0
- package/dist/__tests__/crypto.test.js +181 -0
- package/dist/crypto.d.ts +59 -0
- package/dist/crypto.js +89 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/docs/.nojekyll +1 -0
- package/docs/assets/hierarchy.js +1 -0
- package/docs/assets/highlight.css +78 -0
- package/docs/assets/icons.js +18 -0
- package/docs/assets/icons.svg +1 -0
- package/docs/assets/main.js +60 -0
- package/docs/assets/navigation.js +1 -0
- package/docs/assets/search.js +1 -0
- package/docs/assets/style.css +1633 -0
- package/docs/classes/Crypto.html +20 -0
- package/docs/functions/isCrypto.html +4 -0
- package/docs/hierarchy.html +1 -0
- package/docs/index.html +43 -0
- package/docs/interfaces/CryptoOptions.html +15 -0
- package/docs/modules.html +1 -0
- package/package.json +44 -0
- package/src/__tests__/crypto.test.ts +238 -0
- package/src/crypto.ts +141 -0
- package/src/index.ts +2 -0
- package/tsconfig.json +21 -0
- package/typedoc.json +18 -0
- package/vitest.config.ts +36 -0
package/.hintrc
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Используйте IntelliSense, чтобы узнать о возможных атрибутах.
|
|
3
|
+
// Наведите указатель мыши, чтобы просмотреть описания существующих атрибутов.
|
|
4
|
+
// Для получения дополнительной информации посетите: https://go.microsoft.com/fwlink/?linkid=830387
|
|
5
|
+
"version": "0.2.0",
|
|
6
|
+
"configurations": [
|
|
7
|
+
{
|
|
8
|
+
"type": "node",
|
|
9
|
+
"request": "launch",
|
|
10
|
+
"env": {
|
|
11
|
+
"NODE_OPTIONS": "--experimental-vm-modules"
|
|
12
|
+
},
|
|
13
|
+
"name": "Запустить программу",
|
|
14
|
+
"skipFiles": [
|
|
15
|
+
"<node_internals>/**"
|
|
16
|
+
],
|
|
17
|
+
"program": "${workspaceFolder}\\index.js"
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Common requirements
|
|
6
|
+
|
|
7
|
+
- отвечай на русском языке. Используй английский только если на то есть особые указания
|
|
8
|
+
- комментарии в коде, в JSDoc - используй английский язык
|
|
9
|
+
- отчеты - используй русский язык
|
|
10
|
+
- при создании документов и commit messages НИКОГДА НЕ ДОБАВЛЯЙ в нихх никакой информации о том, что этот текст сгенерирован тобой, либо при твоем участии/соавторстве
|
|
11
|
+
- при формировании и редактировании файлов *.md соблюдай синтаксис MarkDown. Все Markdown-файлы (*.md) ДОЛЖНЫ проходить проверку линтером без ошибок и предупреждений
|
|
12
|
+
- Не вноси изменений в CHANGELOG.md, этот файл формируется автоматически
|
|
13
|
+
- **НИКОГДА НЕ ИСПОЛЬЗУЙ EMOJI** в файлах .md - это строгое требование проекта без исключений
|
|
14
|
+
- при подготовке файлов документации соблюдай структуру каталога docs, правила, изложенные в C:\Repositories\botApp\bot-app-service\docs\CONTRIBUTING.md
|
|
15
|
+
|
|
16
|
+
## Project Overview
|
|
17
|
+
|
|
18
|
+
TypeScript library providing AES-256-CTR encryption/decryption functionality. Wrapper around Node.js native `crypto` module, replacing the previous `aes-js` dependency.
|
|
19
|
+
|
|
20
|
+
## Development Commands
|
|
21
|
+
|
|
22
|
+
### Build
|
|
23
|
+
```bash
|
|
24
|
+
npm run build
|
|
25
|
+
```
|
|
26
|
+
Compiles TypeScript to JavaScript using `tsc`. Output: `dist/` directory with `.js` and `.d.ts` files.
|
|
27
|
+
|
|
28
|
+
### Testing
|
|
29
|
+
```bash
|
|
30
|
+
npm test
|
|
31
|
+
```
|
|
32
|
+
Runs build followed by Node.js native test runner with ts-node loader.
|
|
33
|
+
|
|
34
|
+
To run a specific test file:
|
|
35
|
+
```bash
|
|
36
|
+
npm run build && node --loader ts-node/esm --test src/__tests__/crypto.test.ts
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Documentation Generation
|
|
40
|
+
```bash
|
|
41
|
+
npm run doc
|
|
42
|
+
```
|
|
43
|
+
Generates JSDoc documentation using better-docs template. Output: `docs/` directory.
|
|
44
|
+
|
|
45
|
+
## Architecture
|
|
46
|
+
|
|
47
|
+
### Core Module Structure
|
|
48
|
+
- [src/crypto.ts](src/crypto.ts) - Main `Crypto` class implementation
|
|
49
|
+
- [src/index.ts](src/index.ts) - Module exports
|
|
50
|
+
- [src/__tests__/crypto.test.ts](src/__tests__/crypto.test.ts) - Test suite
|
|
51
|
+
|
|
52
|
+
### Crypto Class Design
|
|
53
|
+
|
|
54
|
+
The `Crypto` class uses Node.js native crypto APIs:
|
|
55
|
+
- **Key derivation**: `pbkdf2Sync` with configurable algorithm (default SHA512), iterations (1000), and key length (32 bytes)
|
|
56
|
+
- **Encryption**: AES-256-CTR mode via `createCipheriv`
|
|
57
|
+
- **Initialization Vector (IV)**: Accepts either Buffer or number (converted to 16-byte Buffer)
|
|
58
|
+
|
|
59
|
+
Constructor supports two signatures:
|
|
60
|
+
1. Individual parameters: `new Crypto(password, salt, algorithm?, iterations?, keyLength?, iv?)`
|
|
61
|
+
2. Options object: `new Crypto({ password, salt, algorithm?, iterations?, keyLength?, iv? })`
|
|
62
|
+
|
|
63
|
+
### Key Implementation Details
|
|
64
|
+
|
|
65
|
+
- IV conversion from number: Uses `Buffer.alloc(16)` with `writeUInt32BE` at offset 12
|
|
66
|
+
- Encryption output: Hex-encoded string
|
|
67
|
+
- Type guard: `isCrypto(object)` function checks for `encrypt` and `decrypt` methods
|
|
68
|
+
- Static method: `Crypto.getUUID()` returns UUIDv4 string using `crypto.randomUUID()`
|
|
69
|
+
|
|
70
|
+
### Module System
|
|
71
|
+
- ES modules (`"type": "module"` in package.json)
|
|
72
|
+
- TypeScript target: ES2022
|
|
73
|
+
- File extensions: Import paths must use `.js` extension (not `.ts`) due to ES module resolution
|
|
74
|
+
|
|
75
|
+
## TypeScript Configuration
|
|
76
|
+
|
|
77
|
+
Strict mode enabled with full type checking. Output includes declaration files for TypeScript consumers.
|
|
78
|
+
|
|
79
|
+
## Testing Approach
|
|
80
|
+
|
|
81
|
+
Tests use Node.js native test runner (`node:test`) with:
|
|
82
|
+
- Encryption/decryption round-trip verification
|
|
83
|
+
- Both constructor signatures
|
|
84
|
+
- Default parameter handling
|
|
85
|
+
- Type guard validation
|
|
86
|
+
- Backward compatibility with previous library version (validates specific encrypted output)
|
|
87
|
+
|
|
88
|
+
## JSDoc Requirements
|
|
89
|
+
|
|
90
|
+
Per user instructions: All modules must include complete JSDoc with module definitions. Comments and JSDoc must be in English.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# MIT License with Commercial Use
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 Vladislav Vnukovskiy
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software.
|
|
6
|
+
|
|
7
|
+
Commercial Use:
|
|
8
|
+
|
|
9
|
+
The user is allowed to use the Software for commercial purposes, subject to the following conditions:
|
|
10
|
+
|
|
11
|
+
The user must agree to share a portion of their revenue with the author of the Software.
|
|
12
|
+
|
|
13
|
+
The author of the Software reserves the right to verify the accuracy and size of the revenue earned by the user through the use of the Software. This provision is a mandatory condition for the commercial use of the Software.
|
|
14
|
+
|
|
15
|
+
If the user does not agree to these conditions, they may not use the Software for commercial purposes.
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
18
|
+
|
|
19
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
# @vvlad1973/crypto
|
|
2
|
+
|
|
3
|
+
A TypeScript library for encrypting and decrypting text using AES-256-CTR encryption with PBKDF2 key derivation.
|
|
4
|
+
|
|
5
|
+
This library uses Node.js native `crypto` module for secure encryption operations.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- AES-256-CTR encryption
|
|
10
|
+
- PBKDF2 key derivation with configurable parameters
|
|
11
|
+
- Support for both number and Buffer initialization vectors
|
|
12
|
+
- TypeScript support with full type definitions
|
|
13
|
+
- Dual API: constructor with options object or separate parameters
|
|
14
|
+
- UUID v4 generation utility
|
|
15
|
+
- Zero external dependencies (uses native Node.js crypto)
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install @vvlad1973/crypto
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
### Importing
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import Crypto, { CryptoOptions, isCrypto } from '@vvlad1973/crypto';
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Basic Usage
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import Crypto from '@vvlad1973/crypto';
|
|
35
|
+
|
|
36
|
+
const password = 'your-password';
|
|
37
|
+
const salt = 'your-salt';
|
|
38
|
+
|
|
39
|
+
// Create an instance using separate parameters
|
|
40
|
+
const crypto = new Crypto(password, salt);
|
|
41
|
+
|
|
42
|
+
// Encrypt a text
|
|
43
|
+
const plainText = 'Hello, World!';
|
|
44
|
+
const encryptedText = crypto.encrypt(plainText);
|
|
45
|
+
console.log('Encrypted:', encryptedText);
|
|
46
|
+
|
|
47
|
+
// Decrypt the text
|
|
48
|
+
const decryptedText = crypto.decrypt(encryptedText);
|
|
49
|
+
console.log('Decrypted:', decryptedText);
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Using Options Object
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import Crypto, { CryptoOptions } from '@vvlad1973/crypto';
|
|
56
|
+
|
|
57
|
+
const options: CryptoOptions = {
|
|
58
|
+
password: 'your-password',
|
|
59
|
+
salt: 'your-salt',
|
|
60
|
+
algorithm: 'SHA512',
|
|
61
|
+
iterations: 1000,
|
|
62
|
+
keyLength: 32,
|
|
63
|
+
iv: 5
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const crypto = new Crypto(options);
|
|
67
|
+
const encrypted = crypto.encrypt('Secret message');
|
|
68
|
+
const decrypted = crypto.decrypt(encrypted);
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Using Buffer IV
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
import Crypto from '@vvlad1973/crypto';
|
|
75
|
+
import { randomBytes } from 'crypto';
|
|
76
|
+
|
|
77
|
+
// Generate a random 16-byte initialization vector
|
|
78
|
+
const ivBuffer = randomBytes(16);
|
|
79
|
+
|
|
80
|
+
const crypto = new Crypto({
|
|
81
|
+
password: 'your-password',
|
|
82
|
+
salt: 'your-salt',
|
|
83
|
+
iv: ivBuffer
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const encrypted = crypto.encrypt('Secret message');
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Generating UUIDs
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
import Crypto from '@vvlad1973/crypto';
|
|
93
|
+
|
|
94
|
+
// Generate a UUID v4
|
|
95
|
+
const uuid = Crypto.getUUID();
|
|
96
|
+
console.log(uuid); // e.g., '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d'
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Type Guard
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
import Crypto, { isCrypto } from '@vvlad1973/crypto';
|
|
103
|
+
|
|
104
|
+
const crypto = new Crypto('password', 'salt');
|
|
105
|
+
|
|
106
|
+
if (isCrypto(crypto)) {
|
|
107
|
+
// TypeScript knows crypto has encrypt/decrypt methods
|
|
108
|
+
const encrypted = crypto.encrypt('text');
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## API
|
|
113
|
+
|
|
114
|
+
### Constructor
|
|
115
|
+
|
|
116
|
+
#### Using separate parameters
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
new Crypto(
|
|
120
|
+
password: string,
|
|
121
|
+
salt: string,
|
|
122
|
+
algorithm?: string,
|
|
123
|
+
iterations?: number,
|
|
124
|
+
keyLength?: number,
|
|
125
|
+
iv?: number | Buffer
|
|
126
|
+
)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
#### Using options object
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
new Crypto(options: CryptoOptions)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**CryptoOptions interface:**
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
interface CryptoOptions {
|
|
139
|
+
password: string; // Password for key derivation
|
|
140
|
+
salt: string; // Salt for key derivation
|
|
141
|
+
algorithm?: string; // Hash algorithm (default: 'SHA512')
|
|
142
|
+
iterations?: number; // PBKDF2 iterations (default: 1000)
|
|
143
|
+
keyLength?: number; // Key length in bytes (default: 32)
|
|
144
|
+
iv?: number | Buffer; // Initialization vector (default: random 16 bytes)
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Parameters:**
|
|
149
|
+
|
|
150
|
+
- `password` - The password used for PBKDF2 key derivation
|
|
151
|
+
- `salt` - The salt used for PBKDF2 key derivation
|
|
152
|
+
- `algorithm` - Hash algorithm for PBKDF2 (default: `'SHA512'`)
|
|
153
|
+
- `iterations` - Number of PBKDF2 iterations (default: `1000`)
|
|
154
|
+
- `keyLength` - Derived key length in bytes (default: `32` for AES-256)
|
|
155
|
+
- `iv` - Initialization vector: either a number (converted to 16-byte Buffer) or a Buffer directly (default: random 16 bytes)
|
|
156
|
+
|
|
157
|
+
### Instance Methods
|
|
158
|
+
|
|
159
|
+
#### encrypt(text: string): string
|
|
160
|
+
|
|
161
|
+
Encrypts the given text using AES-256-CTR encryption.
|
|
162
|
+
|
|
163
|
+
- `text` - The plain text to encrypt
|
|
164
|
+
- **Returns:** The encrypted text as a hexadecimal string
|
|
165
|
+
|
|
166
|
+
#### decrypt(text: string): string
|
|
167
|
+
|
|
168
|
+
Decrypts the given encrypted text using AES-256-CTR decryption.
|
|
169
|
+
|
|
170
|
+
- `text` - The encrypted text as a hexadecimal string
|
|
171
|
+
- **Returns:** The decrypted plain text
|
|
172
|
+
|
|
173
|
+
### Static Methods
|
|
174
|
+
|
|
175
|
+
#### Crypto.getUUID(): string
|
|
176
|
+
|
|
177
|
+
Generates a random UUID v4 string using Node.js native crypto.
|
|
178
|
+
|
|
179
|
+
- **Returns:** A UUID v4 string (e.g., `'9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d'`)
|
|
180
|
+
|
|
181
|
+
### Utility Functions
|
|
182
|
+
|
|
183
|
+
#### isCrypto(object: any): object is Crypto
|
|
184
|
+
|
|
185
|
+
Type guard function to check if an object is an instance of Crypto.
|
|
186
|
+
|
|
187
|
+
- `object` - The object to check
|
|
188
|
+
- **Returns:** `true` if the object is a Crypto instance, `false` otherwise
|
|
189
|
+
|
|
190
|
+
## Testing
|
|
191
|
+
|
|
192
|
+
This library uses Vitest for testing with comprehensive coverage requirements.
|
|
193
|
+
|
|
194
|
+
### Run all tests
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
npm test
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Run tests in watch mode
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
npm run test:watch
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Run tests with UI
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
npm run test:ui
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Generate coverage report
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
npm run test:coverage
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Coverage Requirements
|
|
219
|
+
|
|
220
|
+
- Lines: 90%
|
|
221
|
+
- Functions: 85%
|
|
222
|
+
- Branches: 90%
|
|
223
|
+
- Statements: 90%
|
|
224
|
+
|
|
225
|
+
Current coverage: **100%** across all metrics
|
|
226
|
+
|
|
227
|
+
## Building
|
|
228
|
+
|
|
229
|
+
To build the TypeScript project:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
npm run build
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
This will compile TypeScript files to the `dist` directory with type definitions.
|
|
236
|
+
|
|
237
|
+
## Documentation
|
|
238
|
+
|
|
239
|
+
To generate TypeDoc documentation:
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
npm run doc
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Documentation will be generated in the `docs` directory.
|
|
246
|
+
|
|
247
|
+
## License
|
|
248
|
+
|
|
249
|
+
This project is licensed under the MIT License with Commercial Use - see the LICENSE file for details.
|
|
250
|
+
|
|
251
|
+
## Author
|
|
252
|
+
|
|
253
|
+
Vladislav Vnukovskiy <vvlad1973@gmail.com>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { describe, it, beforeEach, expect } from 'vitest';
|
|
2
|
+
import { randomBytes } from 'crypto';
|
|
3
|
+
import Crypto, { isCrypto } from '../crypto.js';
|
|
4
|
+
describe('Crypto', () => {
|
|
5
|
+
const plainText = 'Hello, World!';
|
|
6
|
+
let options;
|
|
7
|
+
let password;
|
|
8
|
+
let salt;
|
|
9
|
+
let algorithm;
|
|
10
|
+
let iterations;
|
|
11
|
+
let keyLength;
|
|
12
|
+
let iv;
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
options = {
|
|
15
|
+
password: 'testPassword',
|
|
16
|
+
salt: 'testSalt',
|
|
17
|
+
algorithm: 'SHA512',
|
|
18
|
+
iterations: 1000,
|
|
19
|
+
keyLength: 32,
|
|
20
|
+
iv: 5,
|
|
21
|
+
};
|
|
22
|
+
password = 'testPassword';
|
|
23
|
+
salt = 'testSalt';
|
|
24
|
+
algorithm = 'SHA512';
|
|
25
|
+
iterations = 1000;
|
|
26
|
+
keyLength = 32;
|
|
27
|
+
iv = 5;
|
|
28
|
+
});
|
|
29
|
+
it('should initialize with CryptoOptions object', () => {
|
|
30
|
+
const crypto = new Crypto(options);
|
|
31
|
+
expect(crypto).toBeDefined();
|
|
32
|
+
});
|
|
33
|
+
it('should initialize with separate parameters', () => {
|
|
34
|
+
const crypto = new Crypto(password, salt, algorithm, iterations, keyLength, iv);
|
|
35
|
+
expect(crypto).toBeDefined();
|
|
36
|
+
});
|
|
37
|
+
it('should return UUIDv4', () => {
|
|
38
|
+
const crypto = new Crypto(options);
|
|
39
|
+
const uuid = Crypto.getUUID();
|
|
40
|
+
const uuidv4Regex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
41
|
+
expect(uuid).toMatch(uuidv4Regex);
|
|
42
|
+
});
|
|
43
|
+
it('should encrypt and decrypt text correctly using ICryptoOptions', () => {
|
|
44
|
+
const crypto = new Crypto(options);
|
|
45
|
+
const encryptedText = crypto.encrypt(plainText);
|
|
46
|
+
const decryptedText = crypto.decrypt(encryptedText);
|
|
47
|
+
expect(decryptedText).toBe(plainText);
|
|
48
|
+
});
|
|
49
|
+
it('should encrypt and decrypt text correctly using separate parameters', () => {
|
|
50
|
+
const crypto = new Crypto(password, salt, algorithm, iterations, keyLength, iv);
|
|
51
|
+
const encryptedText = crypto.encrypt(plainText);
|
|
52
|
+
const decryptedText = crypto.decrypt(encryptedText);
|
|
53
|
+
expect(decryptedText).toBe(plainText);
|
|
54
|
+
});
|
|
55
|
+
it('should handle default values for optional parameters', () => {
|
|
56
|
+
const cryptoWithDefaults = new Crypto(password, salt);
|
|
57
|
+
const encryptedText = cryptoWithDefaults.encrypt(plainText);
|
|
58
|
+
const decryptedText = cryptoWithDefaults.decrypt(encryptedText);
|
|
59
|
+
expect(decryptedText).toBe(plainText);
|
|
60
|
+
});
|
|
61
|
+
it('should initialize with Buffer IV using options object', () => {
|
|
62
|
+
const ivBuffer = randomBytes(16);
|
|
63
|
+
const crypto = new Crypto({
|
|
64
|
+
password,
|
|
65
|
+
salt,
|
|
66
|
+
algorithm,
|
|
67
|
+
iterations,
|
|
68
|
+
keyLength,
|
|
69
|
+
iv: ivBuffer,
|
|
70
|
+
});
|
|
71
|
+
const encryptedText = crypto.encrypt(plainText);
|
|
72
|
+
const decryptedText = crypto.decrypt(encryptedText);
|
|
73
|
+
expect(decryptedText).toBe(plainText);
|
|
74
|
+
});
|
|
75
|
+
it('should initialize with Buffer IV using separate parameters', () => {
|
|
76
|
+
const ivBuffer = randomBytes(16);
|
|
77
|
+
const crypto = new Crypto(password, salt, algorithm, iterations, keyLength, ivBuffer);
|
|
78
|
+
const encryptedText = crypto.encrypt(plainText);
|
|
79
|
+
const decryptedText = crypto.decrypt(encryptedText);
|
|
80
|
+
expect(decryptedText).toBe(plainText);
|
|
81
|
+
});
|
|
82
|
+
it('should initialize without IV (random generation via options)', () => {
|
|
83
|
+
const crypto1 = new Crypto({ password, salt });
|
|
84
|
+
const crypto2 = new Crypto({ password, salt });
|
|
85
|
+
const encrypted1 = crypto1.encrypt(plainText);
|
|
86
|
+
const encrypted2 = crypto2.encrypt(plainText);
|
|
87
|
+
// Should produce different encrypted results due to different random IVs
|
|
88
|
+
expect(encrypted1).not.toBe(encrypted2);
|
|
89
|
+
});
|
|
90
|
+
it('should handle empty string encryption and decryption', () => {
|
|
91
|
+
const crypto = new Crypto(options);
|
|
92
|
+
const emptyText = '';
|
|
93
|
+
const encryptedText = crypto.encrypt(emptyText);
|
|
94
|
+
const decryptedText = crypto.decrypt(encryptedText);
|
|
95
|
+
expect(decryptedText).toBe(emptyText);
|
|
96
|
+
});
|
|
97
|
+
it('should handle Unicode characters', () => {
|
|
98
|
+
const crypto = new Crypto(options);
|
|
99
|
+
const unicodeText = '🔐 Encryption test 中文 العربية';
|
|
100
|
+
const encryptedText = crypto.encrypt(unicodeText);
|
|
101
|
+
const decryptedText = crypto.decrypt(encryptedText);
|
|
102
|
+
expect(decryptedText).toBe(unicodeText);
|
|
103
|
+
});
|
|
104
|
+
it('should handle different hash algorithms', () => {
|
|
105
|
+
const crypto256 = new Crypto(password, salt, 'sha256', iterations, keyLength, iv);
|
|
106
|
+
const encryptedText = crypto256.encrypt(plainText);
|
|
107
|
+
const decryptedText = crypto256.decrypt(encryptedText);
|
|
108
|
+
expect(decryptedText).toBe(plainText);
|
|
109
|
+
});
|
|
110
|
+
it('should handle different key lengths', () => {
|
|
111
|
+
// AES-256-CTR requires 32 bytes key, testing with valid 32 bytes
|
|
112
|
+
const crypto32 = new Crypto(password, salt, algorithm, iterations, 32, iv);
|
|
113
|
+
const encryptedText = crypto32.encrypt(plainText);
|
|
114
|
+
const decryptedText = crypto32.decrypt(encryptedText);
|
|
115
|
+
expect(decryptedText).toBe(plainText);
|
|
116
|
+
});
|
|
117
|
+
it('should handle different iteration counts', () => {
|
|
118
|
+
const crypto = new Crypto(password, salt, algorithm, 5000, keyLength, iv);
|
|
119
|
+
const encryptedText = crypto.encrypt(plainText);
|
|
120
|
+
const decryptedText = crypto.decrypt(encryptedText);
|
|
121
|
+
expect(decryptedText).toBe(plainText);
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
describe('isCrypto', () => {
|
|
125
|
+
const validCryptoOptions = {
|
|
126
|
+
password: 'testPassword',
|
|
127
|
+
salt: 'testSalt',
|
|
128
|
+
algorithm: 'SHA512',
|
|
129
|
+
iterations: 1000,
|
|
130
|
+
keyLength: 32,
|
|
131
|
+
iv: 5,
|
|
132
|
+
};
|
|
133
|
+
it('should return true for a valid Crypto instance created with ICryptoOptions', () => {
|
|
134
|
+
const crypto = new Crypto(validCryptoOptions);
|
|
135
|
+
expect(isCrypto(crypto)).toBe(true);
|
|
136
|
+
});
|
|
137
|
+
it('should return true for a valid Crypto instance created with separate parameters', () => {
|
|
138
|
+
const crypto = new Crypto(validCryptoOptions.password, validCryptoOptions.salt, validCryptoOptions.algorithm, validCryptoOptions.iterations, validCryptoOptions.keyLength, validCryptoOptions.iv);
|
|
139
|
+
expect(isCrypto(crypto)).toBe(true);
|
|
140
|
+
});
|
|
141
|
+
it('should return false for null', () => {
|
|
142
|
+
const nullObject = null;
|
|
143
|
+
expect(isCrypto(nullObject)).toBe(false);
|
|
144
|
+
});
|
|
145
|
+
it('should return false for undefined', () => {
|
|
146
|
+
const undefinedObject = undefined;
|
|
147
|
+
expect(isCrypto(undefinedObject)).toBe(false);
|
|
148
|
+
});
|
|
149
|
+
it('should return false for a plain object without encrypt and decrypt methods', () => {
|
|
150
|
+
const plainObject = {
|
|
151
|
+
someMethod: () => { },
|
|
152
|
+
};
|
|
153
|
+
expect(isCrypto(plainObject)).toBe(false);
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
describe('Compatibility with previous version', () => {
|
|
157
|
+
const plainText = 'Проверка связи';
|
|
158
|
+
let options;
|
|
159
|
+
let encText = 'a4661cb701751a895f65418ed488faad33da3090d05ad661f0a7a9';
|
|
160
|
+
beforeEach(() => {
|
|
161
|
+
options = {
|
|
162
|
+
algorithm: 'SHA512',
|
|
163
|
+
iv: 5,
|
|
164
|
+
keyLength: 32,
|
|
165
|
+
iterations: 1000,
|
|
166
|
+
password: 'password',
|
|
167
|
+
salt: 'saltsaltsalt',
|
|
168
|
+
};
|
|
169
|
+
});
|
|
170
|
+
it('should return correct string', () => {
|
|
171
|
+
const crypto = new Crypto(options);
|
|
172
|
+
const decryptedText = crypto.decrypt(encText);
|
|
173
|
+
expect(decryptedText).toBe(plainText);
|
|
174
|
+
});
|
|
175
|
+
it('should return correct encrypt-decrypt', () => {
|
|
176
|
+
const crypto = new Crypto(options);
|
|
177
|
+
const encryptedText = crypto.encrypt(plainText);
|
|
178
|
+
const decryptedText = crypto.decrypt(encryptedText);
|
|
179
|
+
expect(decryptedText).toBe(plainText);
|
|
180
|
+
});
|
|
181
|
+
});
|
package/dist/crypto.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks if an object is an instance of Crypto.
|
|
3
|
+
* @param {any} object - The object to check.
|
|
4
|
+
* @returns {boolean} Returns true if the object is an instance of Crypto, false otherwise.
|
|
5
|
+
*/
|
|
6
|
+
export declare function isCrypto(object: any): object is Crypto;
|
|
7
|
+
/**
|
|
8
|
+
* Interface representing the set of parameters to create an instance of the Crypto class.
|
|
9
|
+
* @interface CryptoOptions
|
|
10
|
+
* @property {string} password - The password used for key derivation.
|
|
11
|
+
* @property {string} salt - The salt used for key derivation.
|
|
12
|
+
* @property {string} [algorithm='sha512'] - The hash algorithm to use for key derivation.
|
|
13
|
+
* @property {number} [iterations=1000] - The number of iterations to use for key derivation.
|
|
14
|
+
* @property {number} [keyLength=32] - The length of the derived key in bytes.
|
|
15
|
+
* @property {number|Buffer} [iv] - The initialization vector for the AES encryption.
|
|
16
|
+
*/
|
|
17
|
+
export interface CryptoOptions {
|
|
18
|
+
password: string;
|
|
19
|
+
salt: string;
|
|
20
|
+
algorithm?: string;
|
|
21
|
+
iterations?: number;
|
|
22
|
+
keyLength?: number;
|
|
23
|
+
iv?: number | Buffer;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Class representing a cryptographic utility for encrypting and decrypting text.
|
|
27
|
+
* @class
|
|
28
|
+
* @param {string|CryptoOptions} passwordOrOptions - The password used for key derivation or an options object.
|
|
29
|
+
* @param {string} salt - The salt used for key derivation.
|
|
30
|
+
* @param {string} [algorithm='sha512'] - The hash algorithm to use for key derivation.
|
|
31
|
+
* @param {number} [iterations=1000] - The number of iterations to use for key derivation.
|
|
32
|
+
* @param {number} [keyLength=32] - The length of the derived key in bytes.
|
|
33
|
+
* @param {number|Buffer} [iv] - The initialization vector for the AES encryption.
|
|
34
|
+
*/
|
|
35
|
+
export declare class Crypto {
|
|
36
|
+
private iv;
|
|
37
|
+
private key;
|
|
38
|
+
constructor(password: string, salt: string, algorithm?: string, iterations?: number, keyLength?: number, iv?: number | Buffer);
|
|
39
|
+
constructor(options: CryptoOptions);
|
|
40
|
+
private convertNumberToIV;
|
|
41
|
+
/**
|
|
42
|
+
* Encrypt a text string.
|
|
43
|
+
* @param {string} text - The plain text to encrypt.
|
|
44
|
+
* @returns {string} The encrypted text as a hex string.
|
|
45
|
+
*/
|
|
46
|
+
encrypt(text: string): string;
|
|
47
|
+
/**
|
|
48
|
+
* Decrypt an encrypted text string.
|
|
49
|
+
* @param {string} text - The encrypted text as a hex string.
|
|
50
|
+
* @returns {string} The decrypted plain text.
|
|
51
|
+
*/
|
|
52
|
+
decrypt(text: string): string;
|
|
53
|
+
/**
|
|
54
|
+
* Returns a UUID ver.4 string.
|
|
55
|
+
* @returns {string} UUID ver.4 string.
|
|
56
|
+
*/
|
|
57
|
+
static getUUID(): string;
|
|
58
|
+
}
|
|
59
|
+
export default Crypto;
|