@cryptforge/cryptography 0.2.0
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/README.md +331 -0
- package/dist/index.d.mts +125 -0
- package/dist/index.d.ts +125 -0
- package/dist/index.js +119 -0
- package/dist/index.mjs +91 -0
- package/dist/server.d.mts +172 -0
- package/dist/server.d.ts +172 -0
- package/dist/server.js +213 -0
- package/dist/server.mjs +174 -0
- package/package.json +50 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// src/client/CryptoBrowser.ts
|
|
2
|
+
var CryptoBrowser = class {
|
|
3
|
+
encryptionKey;
|
|
4
|
+
/**
|
|
5
|
+
* Creates a new CryptoBrowser instance.
|
|
6
|
+
* @param getEncryptionKey - Function that returns the encryption key for this instance
|
|
7
|
+
*/
|
|
8
|
+
constructor() {
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Sets the encryption key for the encrypt and decrypt operations.
|
|
12
|
+
* Validates that the key is AES-GCM with 256-bit length for cross-platform compatibility.
|
|
13
|
+
*
|
|
14
|
+
* @param key - The encryption key to set (must be AES-GCM 256-bit)
|
|
15
|
+
* @throws {Error} If key is not AES-GCM or not 256-bit
|
|
16
|
+
*/
|
|
17
|
+
setEncryptionKey = (key) => {
|
|
18
|
+
if (key.algorithm.name !== "AES-GCM") {
|
|
19
|
+
throw new Error(
|
|
20
|
+
`Invalid key algorithm: ${key.algorithm.name}. Key must be AES-GCM for cross-platform compatibility with CryptoServer.`
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
const keyLength = key.algorithm.length;
|
|
24
|
+
if (keyLength !== 256) {
|
|
25
|
+
throw new Error(
|
|
26
|
+
`Invalid key length: ${keyLength} bits. Key must be 256-bit for cross-platform compatibility with CryptoServer (AES-256-GCM).`
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
this.encryptionKey = key;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Creates an encryption function that encrypts string data using AES-GCM encryption.
|
|
33
|
+
* Uses a random initialization vector (IV) for each encryption operation.
|
|
34
|
+
* The IV is prepended to the ciphertext and the result is base64-encoded.
|
|
35
|
+
* Uses the encryption key provided via the `setEncryptionKey` method.
|
|
36
|
+
*
|
|
37
|
+
* @returns A curried function that encrypts data
|
|
38
|
+
*/
|
|
39
|
+
encrypt = () => async (data) => {
|
|
40
|
+
const key = this.encryptionKey;
|
|
41
|
+
if (!key) {
|
|
42
|
+
throw new Error(
|
|
43
|
+
"Encryption key not available. You must call `setEncryptionKey` before using this instance."
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
const iv = crypto.getRandomValues(new Uint8Array(12));
|
|
47
|
+
const encrypted = await crypto.subtle.encrypt(
|
|
48
|
+
{ name: "AES-GCM", iv },
|
|
49
|
+
key,
|
|
50
|
+
new TextEncoder().encode(data)
|
|
51
|
+
);
|
|
52
|
+
const combined = new Uint8Array(iv.length + encrypted.byteLength);
|
|
53
|
+
combined.set(iv);
|
|
54
|
+
combined.set(new Uint8Array(encrypted), iv.length);
|
|
55
|
+
return btoa(String.fromCharCode(...combined));
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Creates a decryption function that decrypts encrypted string data using AES-GCM decryption.
|
|
59
|
+
* Extracts the IV from the beginning of the encrypted data and uses it to decrypt the ciphertext.
|
|
60
|
+
* Uses the encryption key provided via the constructor.
|
|
61
|
+
*
|
|
62
|
+
* @returns A curried function that decrypts data
|
|
63
|
+
*/
|
|
64
|
+
decrypt = () => async (encryptedData) => {
|
|
65
|
+
const key = this.encryptionKey;
|
|
66
|
+
if (!key) {
|
|
67
|
+
throw new Error(
|
|
68
|
+
"Encryption key not available. You must call `setEncryptionKey` before using this instance."
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
const combined = Uint8Array.from(
|
|
72
|
+
atob(encryptedData),
|
|
73
|
+
(c) => c.charCodeAt(0)
|
|
74
|
+
);
|
|
75
|
+
const iv = combined.slice(0, 12);
|
|
76
|
+
const ciphertext = combined.slice(12);
|
|
77
|
+
const decrypted = await crypto.subtle.decrypt(
|
|
78
|
+
{ name: "AES-GCM", iv },
|
|
79
|
+
key,
|
|
80
|
+
ciphertext
|
|
81
|
+
);
|
|
82
|
+
return new TextDecoder().decode(decrypted);
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// src/index.ts
|
|
87
|
+
var version = "0.1.0";
|
|
88
|
+
export {
|
|
89
|
+
CryptoBrowser,
|
|
90
|
+
version
|
|
91
|
+
};
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic interface for cryptographic operations.
|
|
3
|
+
*
|
|
4
|
+
* @template TKey - The encryption key type (CryptoKey for browser, Buffer for Node.js)
|
|
5
|
+
*/
|
|
6
|
+
interface CryptoOperations<TKey = unknown> {
|
|
7
|
+
/**
|
|
8
|
+
* Encryption key for all document operations.
|
|
9
|
+
* All documents are encrypted at rest using this key.
|
|
10
|
+
* Browser implementations use CryptoKey, Node.js implementations use Buffer.
|
|
11
|
+
*/
|
|
12
|
+
setEncryptionKey?: (key: TKey) => void;
|
|
13
|
+
/**
|
|
14
|
+
* Creates an encryption function that encrypts string data using AES-GCM encryption.
|
|
15
|
+
* Returns a curried function that uses the instance's encryption key from `setEncryptionKey`.
|
|
16
|
+
*
|
|
17
|
+
* The returned function signature:
|
|
18
|
+
* - `data`: The plaintext string to encrypt
|
|
19
|
+
* - Returns: A promise resolving to the encrypted data as a string
|
|
20
|
+
*/
|
|
21
|
+
encrypt: () => (data: string) => Promise<string>;
|
|
22
|
+
/**
|
|
23
|
+
* Creates a decryption function that decrypts encrypted string data using AES-GCM decryption.
|
|
24
|
+
* Returns a curried function that uses the instance's encryption key from `setEncryptionKey`.
|
|
25
|
+
*
|
|
26
|
+
* The returned function signature:
|
|
27
|
+
* - `encryptedData`: The encrypted string data to decrypt
|
|
28
|
+
* - Returns: A promise resolving to the decrypted plaintext string
|
|
29
|
+
*/
|
|
30
|
+
decrypt: () => (encryptedData: string) => Promise<string>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Configuration options for cryptographic operations
|
|
34
|
+
*/
|
|
35
|
+
interface CryptoConfig {
|
|
36
|
+
/**
|
|
37
|
+
* Algorithm to use for encryption/decryption
|
|
38
|
+
*/
|
|
39
|
+
algorithm?: string;
|
|
40
|
+
/**
|
|
41
|
+
* Key derivation iterations (if applicable)
|
|
42
|
+
*/
|
|
43
|
+
iterations?: number;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Result of an encryption operation
|
|
47
|
+
*/
|
|
48
|
+
interface EncryptionResult {
|
|
49
|
+
/**
|
|
50
|
+
* Encrypted data
|
|
51
|
+
*/
|
|
52
|
+
ciphertext: Uint8Array;
|
|
53
|
+
/**
|
|
54
|
+
* Initialization vector or nonce
|
|
55
|
+
*/
|
|
56
|
+
iv: Uint8Array;
|
|
57
|
+
/**
|
|
58
|
+
* Authentication tag (for authenticated encryption)
|
|
59
|
+
*/
|
|
60
|
+
tag?: Uint8Array;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Result of a decryption operation
|
|
64
|
+
*/
|
|
65
|
+
interface DecryptionResult {
|
|
66
|
+
/**
|
|
67
|
+
* Decrypted plaintext data
|
|
68
|
+
*/
|
|
69
|
+
plaintext: Uint8Array;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Key pair for asymmetric cryptography
|
|
73
|
+
*/
|
|
74
|
+
interface KeyPair {
|
|
75
|
+
/**
|
|
76
|
+
* Public key
|
|
77
|
+
*/
|
|
78
|
+
publicKey: Uint8Array;
|
|
79
|
+
/**
|
|
80
|
+
* Private key
|
|
81
|
+
*/
|
|
82
|
+
privateKey: Uint8Array;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Browser implementation of cryptographic operations using Web Crypto API.
|
|
87
|
+
* Uses CryptoKey for encryption/decryption operations.
|
|
88
|
+
*/
|
|
89
|
+
declare class CryptoBrowser implements CryptoOperations<CryptoKey> {
|
|
90
|
+
private encryptionKey?;
|
|
91
|
+
/**
|
|
92
|
+
* Creates a new CryptoBrowser instance.
|
|
93
|
+
* @param getEncryptionKey - Function that returns the encryption key for this instance
|
|
94
|
+
*/
|
|
95
|
+
constructor();
|
|
96
|
+
/**
|
|
97
|
+
* Sets the encryption key for the encrypt and decrypt operations.
|
|
98
|
+
* Validates that the key is AES-GCM with 256-bit length for cross-platform compatibility.
|
|
99
|
+
*
|
|
100
|
+
* @param key - The encryption key to set (must be AES-GCM 256-bit)
|
|
101
|
+
* @throws {Error} If key is not AES-GCM or not 256-bit
|
|
102
|
+
*/
|
|
103
|
+
setEncryptionKey: (key: CryptoKey) => void;
|
|
104
|
+
/**
|
|
105
|
+
* Creates an encryption function that encrypts string data using AES-GCM encryption.
|
|
106
|
+
* Uses a random initialization vector (IV) for each encryption operation.
|
|
107
|
+
* The IV is prepended to the ciphertext and the result is base64-encoded.
|
|
108
|
+
* Uses the encryption key provided via the `setEncryptionKey` method.
|
|
109
|
+
*
|
|
110
|
+
* @returns A curried function that encrypts data
|
|
111
|
+
*/
|
|
112
|
+
encrypt: () => (data: string) => Promise<string>;
|
|
113
|
+
/**
|
|
114
|
+
* Creates a decryption function that decrypts encrypted string data using AES-GCM decryption.
|
|
115
|
+
* Extracts the IV from the beginning of the encrypted data and uses it to decrypt the ciphertext.
|
|
116
|
+
* Uses the encryption key provided via the constructor.
|
|
117
|
+
*
|
|
118
|
+
* @returns A curried function that decrypts data
|
|
119
|
+
*/
|
|
120
|
+
decrypt: () => (encryptedData: string) => Promise<string>;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Server/Node.js implementation of cryptographic operations using Node.js crypto module.
|
|
125
|
+
* Uses Buffer for encryption/decryption operations.
|
|
126
|
+
*
|
|
127
|
+
* IMPORTANT: This implementation is compatible with CryptoBrowser - data encrypted
|
|
128
|
+
* by CryptoBrowser can be decrypted by CryptoServer and vice versa.
|
|
129
|
+
*/
|
|
130
|
+
declare class CryptoServer implements CryptoOperations<Buffer> {
|
|
131
|
+
/**
|
|
132
|
+
* The encryption key for the encrypt and decrypt operations.
|
|
133
|
+
*/
|
|
134
|
+
private encryptionKey?;
|
|
135
|
+
/**
|
|
136
|
+
* Creates a new CryptoServer instance.
|
|
137
|
+
*/
|
|
138
|
+
constructor();
|
|
139
|
+
/**
|
|
140
|
+
* Sets the encryption key for the encrypt and decrypt operations.
|
|
141
|
+
* Validates that the key is 32 bytes (256 bits) for AES-256-GCM.
|
|
142
|
+
*
|
|
143
|
+
* @param key - The encryption key to set (must be 32 bytes / 256 bits)
|
|
144
|
+
* @throws {Error} If key is not 32 bytes
|
|
145
|
+
*/
|
|
146
|
+
setEncryptionKey: (key: Buffer) => void;
|
|
147
|
+
/**
|
|
148
|
+
* Creates an encryption function that encrypts string data using AES-GCM encryption.
|
|
149
|
+
* Uses a random initialization vector (IV) for each encryption operation.
|
|
150
|
+
* The IV is prepended to the ciphertext and the result is base64-encoded.
|
|
151
|
+
* Uses the encryption key provided via the `setEncryptionKey` method.
|
|
152
|
+
*
|
|
153
|
+
* Format matches CryptoBrowser: [IV (12 bytes)][Ciphertext + AuthTag (16 bytes)] -> base64
|
|
154
|
+
*
|
|
155
|
+
* @returns A curried function that encrypts data
|
|
156
|
+
*/
|
|
157
|
+
encrypt: () => (data: string) => Promise<string>;
|
|
158
|
+
/**
|
|
159
|
+
* Creates a decryption function that decrypts encrypted string data using AES-GCM decryption.
|
|
160
|
+
* Extracts the IV from the beginning of the encrypted data and uses it to decrypt the ciphertext.
|
|
161
|
+
* Uses the encryption key provided via the constructor.
|
|
162
|
+
*
|
|
163
|
+
* Format matches CryptoBrowser: base64 -> [IV (12 bytes)][Ciphertext + AuthTag (16 bytes)]
|
|
164
|
+
*
|
|
165
|
+
* @returns A curried function that decrypts data
|
|
166
|
+
*/
|
|
167
|
+
decrypt: () => (encryptedData: string) => Promise<string>;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
declare const version = "0.1.0-server";
|
|
171
|
+
|
|
172
|
+
export { CryptoBrowser, type CryptoConfig, type CryptoOperations, CryptoServer, type DecryptionResult, type EncryptionResult, type KeyPair, version };
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic interface for cryptographic operations.
|
|
3
|
+
*
|
|
4
|
+
* @template TKey - The encryption key type (CryptoKey for browser, Buffer for Node.js)
|
|
5
|
+
*/
|
|
6
|
+
interface CryptoOperations<TKey = unknown> {
|
|
7
|
+
/**
|
|
8
|
+
* Encryption key for all document operations.
|
|
9
|
+
* All documents are encrypted at rest using this key.
|
|
10
|
+
* Browser implementations use CryptoKey, Node.js implementations use Buffer.
|
|
11
|
+
*/
|
|
12
|
+
setEncryptionKey?: (key: TKey) => void;
|
|
13
|
+
/**
|
|
14
|
+
* Creates an encryption function that encrypts string data using AES-GCM encryption.
|
|
15
|
+
* Returns a curried function that uses the instance's encryption key from `setEncryptionKey`.
|
|
16
|
+
*
|
|
17
|
+
* The returned function signature:
|
|
18
|
+
* - `data`: The plaintext string to encrypt
|
|
19
|
+
* - Returns: A promise resolving to the encrypted data as a string
|
|
20
|
+
*/
|
|
21
|
+
encrypt: () => (data: string) => Promise<string>;
|
|
22
|
+
/**
|
|
23
|
+
* Creates a decryption function that decrypts encrypted string data using AES-GCM decryption.
|
|
24
|
+
* Returns a curried function that uses the instance's encryption key from `setEncryptionKey`.
|
|
25
|
+
*
|
|
26
|
+
* The returned function signature:
|
|
27
|
+
* - `encryptedData`: The encrypted string data to decrypt
|
|
28
|
+
* - Returns: A promise resolving to the decrypted plaintext string
|
|
29
|
+
*/
|
|
30
|
+
decrypt: () => (encryptedData: string) => Promise<string>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Configuration options for cryptographic operations
|
|
34
|
+
*/
|
|
35
|
+
interface CryptoConfig {
|
|
36
|
+
/**
|
|
37
|
+
* Algorithm to use for encryption/decryption
|
|
38
|
+
*/
|
|
39
|
+
algorithm?: string;
|
|
40
|
+
/**
|
|
41
|
+
* Key derivation iterations (if applicable)
|
|
42
|
+
*/
|
|
43
|
+
iterations?: number;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Result of an encryption operation
|
|
47
|
+
*/
|
|
48
|
+
interface EncryptionResult {
|
|
49
|
+
/**
|
|
50
|
+
* Encrypted data
|
|
51
|
+
*/
|
|
52
|
+
ciphertext: Uint8Array;
|
|
53
|
+
/**
|
|
54
|
+
* Initialization vector or nonce
|
|
55
|
+
*/
|
|
56
|
+
iv: Uint8Array;
|
|
57
|
+
/**
|
|
58
|
+
* Authentication tag (for authenticated encryption)
|
|
59
|
+
*/
|
|
60
|
+
tag?: Uint8Array;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Result of a decryption operation
|
|
64
|
+
*/
|
|
65
|
+
interface DecryptionResult {
|
|
66
|
+
/**
|
|
67
|
+
* Decrypted plaintext data
|
|
68
|
+
*/
|
|
69
|
+
plaintext: Uint8Array;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Key pair for asymmetric cryptography
|
|
73
|
+
*/
|
|
74
|
+
interface KeyPair {
|
|
75
|
+
/**
|
|
76
|
+
* Public key
|
|
77
|
+
*/
|
|
78
|
+
publicKey: Uint8Array;
|
|
79
|
+
/**
|
|
80
|
+
* Private key
|
|
81
|
+
*/
|
|
82
|
+
privateKey: Uint8Array;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Browser implementation of cryptographic operations using Web Crypto API.
|
|
87
|
+
* Uses CryptoKey for encryption/decryption operations.
|
|
88
|
+
*/
|
|
89
|
+
declare class CryptoBrowser implements CryptoOperations<CryptoKey> {
|
|
90
|
+
private encryptionKey?;
|
|
91
|
+
/**
|
|
92
|
+
* Creates a new CryptoBrowser instance.
|
|
93
|
+
* @param getEncryptionKey - Function that returns the encryption key for this instance
|
|
94
|
+
*/
|
|
95
|
+
constructor();
|
|
96
|
+
/**
|
|
97
|
+
* Sets the encryption key for the encrypt and decrypt operations.
|
|
98
|
+
* Validates that the key is AES-GCM with 256-bit length for cross-platform compatibility.
|
|
99
|
+
*
|
|
100
|
+
* @param key - The encryption key to set (must be AES-GCM 256-bit)
|
|
101
|
+
* @throws {Error} If key is not AES-GCM or not 256-bit
|
|
102
|
+
*/
|
|
103
|
+
setEncryptionKey: (key: CryptoKey) => void;
|
|
104
|
+
/**
|
|
105
|
+
* Creates an encryption function that encrypts string data using AES-GCM encryption.
|
|
106
|
+
* Uses a random initialization vector (IV) for each encryption operation.
|
|
107
|
+
* The IV is prepended to the ciphertext and the result is base64-encoded.
|
|
108
|
+
* Uses the encryption key provided via the `setEncryptionKey` method.
|
|
109
|
+
*
|
|
110
|
+
* @returns A curried function that encrypts data
|
|
111
|
+
*/
|
|
112
|
+
encrypt: () => (data: string) => Promise<string>;
|
|
113
|
+
/**
|
|
114
|
+
* Creates a decryption function that decrypts encrypted string data using AES-GCM decryption.
|
|
115
|
+
* Extracts the IV from the beginning of the encrypted data and uses it to decrypt the ciphertext.
|
|
116
|
+
* Uses the encryption key provided via the constructor.
|
|
117
|
+
*
|
|
118
|
+
* @returns A curried function that decrypts data
|
|
119
|
+
*/
|
|
120
|
+
decrypt: () => (encryptedData: string) => Promise<string>;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Server/Node.js implementation of cryptographic operations using Node.js crypto module.
|
|
125
|
+
* Uses Buffer for encryption/decryption operations.
|
|
126
|
+
*
|
|
127
|
+
* IMPORTANT: This implementation is compatible with CryptoBrowser - data encrypted
|
|
128
|
+
* by CryptoBrowser can be decrypted by CryptoServer and vice versa.
|
|
129
|
+
*/
|
|
130
|
+
declare class CryptoServer implements CryptoOperations<Buffer> {
|
|
131
|
+
/**
|
|
132
|
+
* The encryption key for the encrypt and decrypt operations.
|
|
133
|
+
*/
|
|
134
|
+
private encryptionKey?;
|
|
135
|
+
/**
|
|
136
|
+
* Creates a new CryptoServer instance.
|
|
137
|
+
*/
|
|
138
|
+
constructor();
|
|
139
|
+
/**
|
|
140
|
+
* Sets the encryption key for the encrypt and decrypt operations.
|
|
141
|
+
* Validates that the key is 32 bytes (256 bits) for AES-256-GCM.
|
|
142
|
+
*
|
|
143
|
+
* @param key - The encryption key to set (must be 32 bytes / 256 bits)
|
|
144
|
+
* @throws {Error} If key is not 32 bytes
|
|
145
|
+
*/
|
|
146
|
+
setEncryptionKey: (key: Buffer) => void;
|
|
147
|
+
/**
|
|
148
|
+
* Creates an encryption function that encrypts string data using AES-GCM encryption.
|
|
149
|
+
* Uses a random initialization vector (IV) for each encryption operation.
|
|
150
|
+
* The IV is prepended to the ciphertext and the result is base64-encoded.
|
|
151
|
+
* Uses the encryption key provided via the `setEncryptionKey` method.
|
|
152
|
+
*
|
|
153
|
+
* Format matches CryptoBrowser: [IV (12 bytes)][Ciphertext + AuthTag (16 bytes)] -> base64
|
|
154
|
+
*
|
|
155
|
+
* @returns A curried function that encrypts data
|
|
156
|
+
*/
|
|
157
|
+
encrypt: () => (data: string) => Promise<string>;
|
|
158
|
+
/**
|
|
159
|
+
* Creates a decryption function that decrypts encrypted string data using AES-GCM decryption.
|
|
160
|
+
* Extracts the IV from the beginning of the encrypted data and uses it to decrypt the ciphertext.
|
|
161
|
+
* Uses the encryption key provided via the constructor.
|
|
162
|
+
*
|
|
163
|
+
* Format matches CryptoBrowser: base64 -> [IV (12 bytes)][Ciphertext + AuthTag (16 bytes)]
|
|
164
|
+
*
|
|
165
|
+
* @returns A curried function that decrypts data
|
|
166
|
+
*/
|
|
167
|
+
decrypt: () => (encryptedData: string) => Promise<string>;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
declare const version = "0.1.0-server";
|
|
171
|
+
|
|
172
|
+
export { CryptoBrowser, type CryptoConfig, type CryptoOperations, CryptoServer, type DecryptionResult, type EncryptionResult, type KeyPair, version };
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/server.ts
|
|
31
|
+
var server_exports = {};
|
|
32
|
+
__export(server_exports, {
|
|
33
|
+
CryptoBrowser: () => CryptoBrowser,
|
|
34
|
+
CryptoServer: () => CryptoServer,
|
|
35
|
+
version: () => version
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(server_exports);
|
|
38
|
+
|
|
39
|
+
// src/client/CryptoBrowser.ts
|
|
40
|
+
var CryptoBrowser = class {
|
|
41
|
+
encryptionKey;
|
|
42
|
+
/**
|
|
43
|
+
* Creates a new CryptoBrowser instance.
|
|
44
|
+
* @param getEncryptionKey - Function that returns the encryption key for this instance
|
|
45
|
+
*/
|
|
46
|
+
constructor() {
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Sets the encryption key for the encrypt and decrypt operations.
|
|
50
|
+
* Validates that the key is AES-GCM with 256-bit length for cross-platform compatibility.
|
|
51
|
+
*
|
|
52
|
+
* @param key - The encryption key to set (must be AES-GCM 256-bit)
|
|
53
|
+
* @throws {Error} If key is not AES-GCM or not 256-bit
|
|
54
|
+
*/
|
|
55
|
+
setEncryptionKey = (key) => {
|
|
56
|
+
if (key.algorithm.name !== "AES-GCM") {
|
|
57
|
+
throw new Error(
|
|
58
|
+
`Invalid key algorithm: ${key.algorithm.name}. Key must be AES-GCM for cross-platform compatibility with CryptoServer.`
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
const keyLength = key.algorithm.length;
|
|
62
|
+
if (keyLength !== 256) {
|
|
63
|
+
throw new Error(
|
|
64
|
+
`Invalid key length: ${keyLength} bits. Key must be 256-bit for cross-platform compatibility with CryptoServer (AES-256-GCM).`
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
this.encryptionKey = key;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Creates an encryption function that encrypts string data using AES-GCM encryption.
|
|
71
|
+
* Uses a random initialization vector (IV) for each encryption operation.
|
|
72
|
+
* The IV is prepended to the ciphertext and the result is base64-encoded.
|
|
73
|
+
* Uses the encryption key provided via the `setEncryptionKey` method.
|
|
74
|
+
*
|
|
75
|
+
* @returns A curried function that encrypts data
|
|
76
|
+
*/
|
|
77
|
+
encrypt = () => async (data) => {
|
|
78
|
+
const key = this.encryptionKey;
|
|
79
|
+
if (!key) {
|
|
80
|
+
throw new Error(
|
|
81
|
+
"Encryption key not available. You must call `setEncryptionKey` before using this instance."
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
const iv = crypto.getRandomValues(new Uint8Array(12));
|
|
85
|
+
const encrypted = await crypto.subtle.encrypt(
|
|
86
|
+
{ name: "AES-GCM", iv },
|
|
87
|
+
key,
|
|
88
|
+
new TextEncoder().encode(data)
|
|
89
|
+
);
|
|
90
|
+
const combined = new Uint8Array(iv.length + encrypted.byteLength);
|
|
91
|
+
combined.set(iv);
|
|
92
|
+
combined.set(new Uint8Array(encrypted), iv.length);
|
|
93
|
+
return btoa(String.fromCharCode(...combined));
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Creates a decryption function that decrypts encrypted string data using AES-GCM decryption.
|
|
97
|
+
* Extracts the IV from the beginning of the encrypted data and uses it to decrypt the ciphertext.
|
|
98
|
+
* Uses the encryption key provided via the constructor.
|
|
99
|
+
*
|
|
100
|
+
* @returns A curried function that decrypts data
|
|
101
|
+
*/
|
|
102
|
+
decrypt = () => async (encryptedData) => {
|
|
103
|
+
const key = this.encryptionKey;
|
|
104
|
+
if (!key) {
|
|
105
|
+
throw new Error(
|
|
106
|
+
"Encryption key not available. You must call `setEncryptionKey` before using this instance."
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
const combined = Uint8Array.from(
|
|
110
|
+
atob(encryptedData),
|
|
111
|
+
(c) => c.charCodeAt(0)
|
|
112
|
+
);
|
|
113
|
+
const iv = combined.slice(0, 12);
|
|
114
|
+
const ciphertext = combined.slice(12);
|
|
115
|
+
const decrypted = await crypto.subtle.decrypt(
|
|
116
|
+
{ name: "AES-GCM", iv },
|
|
117
|
+
key,
|
|
118
|
+
ciphertext
|
|
119
|
+
);
|
|
120
|
+
return new TextDecoder().decode(decrypted);
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
// src/server/CryptoServer.ts
|
|
125
|
+
var import_crypto = __toESM(require("crypto"));
|
|
126
|
+
var CryptoServer = class {
|
|
127
|
+
/**
|
|
128
|
+
* The encryption key for the encrypt and decrypt operations.
|
|
129
|
+
*/
|
|
130
|
+
encryptionKey;
|
|
131
|
+
/**
|
|
132
|
+
* Creates a new CryptoServer instance.
|
|
133
|
+
*/
|
|
134
|
+
constructor() {
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Sets the encryption key for the encrypt and decrypt operations.
|
|
138
|
+
* Validates that the key is 32 bytes (256 bits) for AES-256-GCM.
|
|
139
|
+
*
|
|
140
|
+
* @param key - The encryption key to set (must be 32 bytes / 256 bits)
|
|
141
|
+
* @throws {Error} If key is not 32 bytes
|
|
142
|
+
*/
|
|
143
|
+
setEncryptionKey = (key) => {
|
|
144
|
+
if (key.length !== 32) {
|
|
145
|
+
throw new Error(
|
|
146
|
+
`Invalid key length: ${key.length} bytes (${key.length * 8} bits). Key must be 32 bytes (256 bits) for AES-256-GCM cross-platform compatibility with CryptoBrowser.`
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
this.encryptionKey = key;
|
|
150
|
+
};
|
|
151
|
+
/**
|
|
152
|
+
* Creates an encryption function that encrypts string data using AES-GCM encryption.
|
|
153
|
+
* Uses a random initialization vector (IV) for each encryption operation.
|
|
154
|
+
* The IV is prepended to the ciphertext and the result is base64-encoded.
|
|
155
|
+
* Uses the encryption key provided via the `setEncryptionKey` method.
|
|
156
|
+
*
|
|
157
|
+
* Format matches CryptoBrowser: [IV (12 bytes)][Ciphertext + AuthTag (16 bytes)] -> base64
|
|
158
|
+
*
|
|
159
|
+
* @returns A curried function that encrypts data
|
|
160
|
+
*/
|
|
161
|
+
encrypt = () => async (data) => {
|
|
162
|
+
const key = this.encryptionKey;
|
|
163
|
+
if (!key) {
|
|
164
|
+
throw new Error(
|
|
165
|
+
"Encryption key not available. You must call `setEncryptionKey` before using this instance."
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
const iv = import_crypto.default.randomBytes(12);
|
|
169
|
+
const cipher = import_crypto.default.createCipheriv("aes-256-gcm", key, iv);
|
|
170
|
+
let encrypted = cipher.update(data, "utf8");
|
|
171
|
+
encrypted = Buffer.concat([encrypted, cipher.final()]);
|
|
172
|
+
const authTag = cipher.getAuthTag();
|
|
173
|
+
const ciphertextWithAuthTag = Buffer.concat([encrypted, authTag]);
|
|
174
|
+
const combined = Buffer.concat([iv, ciphertextWithAuthTag]);
|
|
175
|
+
return combined.toString("base64");
|
|
176
|
+
};
|
|
177
|
+
/**
|
|
178
|
+
* Creates a decryption function that decrypts encrypted string data using AES-GCM decryption.
|
|
179
|
+
* Extracts the IV from the beginning of the encrypted data and uses it to decrypt the ciphertext.
|
|
180
|
+
* Uses the encryption key provided via the constructor.
|
|
181
|
+
*
|
|
182
|
+
* Format matches CryptoBrowser: base64 -> [IV (12 bytes)][Ciphertext + AuthTag (16 bytes)]
|
|
183
|
+
*
|
|
184
|
+
* @returns A curried function that decrypts data
|
|
185
|
+
*/
|
|
186
|
+
decrypt = () => async (encryptedData) => {
|
|
187
|
+
const key = this.encryptionKey;
|
|
188
|
+
if (!key) {
|
|
189
|
+
throw new Error(
|
|
190
|
+
"Encryption key not available. You must call `setEncryptionKey` before using this instance."
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
const combined = Buffer.from(encryptedData, "base64");
|
|
194
|
+
const iv = combined.slice(0, 12);
|
|
195
|
+
const ciphertextWithAuthTag = combined.slice(12);
|
|
196
|
+
const authTag = ciphertextWithAuthTag.slice(-16);
|
|
197
|
+
const ciphertext = ciphertextWithAuthTag.slice(0, -16);
|
|
198
|
+
const decipher = import_crypto.default.createDecipheriv("aes-256-gcm", key, iv);
|
|
199
|
+
decipher.setAuthTag(authTag);
|
|
200
|
+
let decrypted = decipher.update(ciphertext);
|
|
201
|
+
decrypted = Buffer.concat([decrypted, decipher.final()]);
|
|
202
|
+
return decrypted.toString("utf8");
|
|
203
|
+
};
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
// src/server.ts
|
|
207
|
+
var version = "0.1.0-server";
|
|
208
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
209
|
+
0 && (module.exports = {
|
|
210
|
+
CryptoBrowser,
|
|
211
|
+
CryptoServer,
|
|
212
|
+
version
|
|
213
|
+
});
|