@pulkitsinha007/hybrid-crypto-js 1.2.0 → 1.2.2

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 CHANGED
@@ -1,32 +1,203 @@
1
- # Hybrid Crypto dummy set-up
1
+ # @pulkitsinha007/hybrid-crypto-js
2
2
 
3
- This example demonstrates how to use the `hybrid-crypto-js` library in a full-stack Node.js application.
3
+ A robust hybrid encryption library for high-security applications, implementing industry-standard **RSA-OAEP** and **AES-GCM** algorithms. This package is designed to facilitate secure, two-way communication by combining the performance of symmetric encryption with the security of asymmetric key exchange, ensuring the symmetric key is never exposed in its unwrapped form during transit.
4
4
 
5
- ## Structure
5
+ ## Installation
6
6
 
7
- - **Backend**: A Node.js HTTP server that manages its own RSA key pair, exposes its Public Key, and handles decryption of client messages and encryption of secret messages for clients.
8
- - **Frontend**: A simple HTML/JS page that generates a client-side RSA key pair, fetches the server's Public Key, and demonstrates secure 2-way communication.
7
+ ```bash
8
+ npm install @pulkitsinha007/hybrid-crypto-js
9
+ ```
9
10
 
10
- ## Running the Example
11
+ ## Overview
11
12
 
12
- 1. Ensure you are in the root of the repository.
13
- 2. Run the server:
14
- ```bash
15
- node examples/full-stack/backend/server.js
16
- ```
17
- 3. Open your browser and navigate to:
18
- [http://localhost:3000](http://localhost:3000)
13
+ This package is ideal for scenarios requiring end-to-end encryption where:
14
+ - **High Security** is paramount (e.g., financial data, personal identifiable information).
15
+ - **Industry Standards** must be met (utilizing native Web Crypto API and Node.js Crypto).
16
+ - **Two-way Communication** is needed, allowing the server to respond securely using the same session key established by the client.
19
17
 
20
- ## How it works
18
+ ## API Documentation
21
19
 
22
- 1. **Client -> Server Encryption**:
23
- - The Client fetches the Server's Public Key.
24
- - The Client encrypts a message using `encrypt(message, serverPublicKey)`.
25
- - The Client sends the encrypted package to the Server.
26
- - The Server decrypts it using its Private Key.
20
+ ### `generateKeyPair()`
21
+ Generates a new RSA-OAEP key pair (2048-bit).
22
+ - **Returns**: `Promise<{publicKey: string, privateKey: string}>` (Base64 encoded)
27
23
 
28
- 2. **Server -> Client Encryption**:
29
- - The Client sends its Public Key to the Server.
30
- - The Server encrypts a message using `encrypt(message, clientPublicKey)`.
31
- - The Server sends the encrypted package to the Client.
32
- - The Client decrypts it using its Private Key.
24
+ ```javascript
25
+ import { generateKeyPair } from '@pulkitsinha007/hybrid-crypto-js';
26
+
27
+ const { publicKey, privateKey } = await generateKeyPair();
28
+ console.log('Public Key:', publicKey);
29
+ ```
30
+
31
+ ### `createSymmetricKey()`
32
+ Generates a random AES-GCM symmetric key (256-bit).
33
+ - **Returns**: `Promise<CryptoKey>`
34
+
35
+ ```javascript
36
+ import { createSymmetricKey } from '@pulkitsinha007/hybrid-crypto-js';
37
+
38
+ const sessionKey = await createSymmetricKey();
39
+ ```
40
+
41
+ ### `wrapKey(key, publicKey)`
42
+ Encrypts (wraps) a symmetric key using an RSA public key.
43
+ - **Parameters**:
44
+ - `key`: `CryptoKey` - The symmetric key to wrap.
45
+ - `publicKey`: `string` - The RSA public key (Base64).
46
+ - **Returns**: `Promise<string>` (Base64 encoded wrapped key)
47
+
48
+ ```javascript
49
+ import { wrapKey } from '@pulkitsinha007/hybrid-crypto-js';
50
+
51
+ const wrappedKey = await wrapKey(sessionKey, serverPublicKey);
52
+ ```
53
+
54
+ ### `unwrapKey(wrappedKey, privateKey)`
55
+ Decrypts (unwraps) a symmetric key using an RSA private key.
56
+ - **Parameters**:
57
+ - `wrappedKey`: `string` - The wrapped key (Base64).
58
+ - `privateKey`: `string` - The RSA private key (Base64).
59
+ - **Returns**: `Promise<CryptoKey>`
60
+
61
+ ```javascript
62
+ import { unwrapKey } from '@pulkitsinha007/hybrid-crypto-js';
63
+
64
+ const sessionKey = await unwrapKey(wrappedKey, serverPrivateKey);
65
+ ```
66
+
67
+ ### `encryptWithSymmetricKey(data, key)`
68
+ Encrypts data using an AES symmetric key.
69
+ - **Parameters**:
70
+ - `data`: `string | object` - The payload to encrypt.
71
+ - `key`: `CryptoKey` - The AES key.
72
+ - **Returns**: `Promise<{encryptedData: string, iv: string}>`
73
+
74
+ ```javascript
75
+ import { encryptWithSymmetricKey } from '@pulkitsinha007/hybrid-crypto-js';
76
+
77
+ const { encryptedData, iv } = await encryptWithSymmetricKey({ msg: "Hello" }, sessionKey);
78
+ ```
79
+
80
+ ### `decryptWithSymmetricKey(encryptedPackage, key)`
81
+ Decrypts data using an AES symmetric key.
82
+ - **Parameters**:
83
+ - `encryptedPackage`: `{encryptedData: string, iv: string}`.
84
+ - `key`: `CryptoKey`.
85
+ - **Returns**: `Promise<string | object>`
86
+
87
+ ```javascript
88
+ import { decryptWithSymmetricKey } from '@pulkitsinha007/hybrid-crypto-js';
89
+
90
+ const data = await decryptWithSymmetricKey({ encryptedData, iv }, sessionKey);
91
+ ```
92
+
93
+ ---
94
+
95
+ ## Backend Setup (Dummy Application)
96
+
97
+ This section demonstrates how to set up a simple backend (e.g., using Node.js/Express) that generates an RSA key pair on startup and handles secure requests.
98
+
99
+ ```javascript
100
+ import http from 'http';
101
+ import {
102
+ generateKeyPair,
103
+ unwrapKey,
104
+ decryptWithSymmetricKey,
105
+ encryptWithSymmetricKey
106
+ } from '@pulkitsinha007/hybrid-crypto-js';
107
+
108
+ let publicKey, privateKey;
109
+
110
+ // 1. Generate RSA Keys on Startup
111
+ (async () => {
112
+ const keys = await generateKeyPair();
113
+ publicKey = keys.publicKey;
114
+ privateKey = keys.privateKey;
115
+ console.log('Server keys ready.');
116
+ })();
117
+
118
+ const server = http.createServer(async (req, res) => {
119
+ // 2. Expose Public Key Endpoint
120
+ if (req.url === '/api/public-key' && req.method === 'GET') {
121
+ res.writeHead(200, { 'Content-Type': 'application/json' });
122
+ res.end(JSON.stringify({ publicKey }));
123
+ return;
124
+ }
125
+
126
+ // 3. Handle Secure Submission
127
+ if (req.url === '/api/submit' && req.method === 'POST') {
128
+ let body = '';
129
+ req.on('data', chunk => body += chunk);
130
+ req.on('end', async () => {
131
+ try {
132
+ const { wrappedKey, encryptedPackage } = JSON.parse(body);
133
+
134
+ // A. Unwrap the session key using Server Private Key
135
+ const sessionKey = await unwrapKey(wrappedKey, privateKey);
136
+
137
+ // B. Decrypt the client's message
138
+ const decryptedData = await decryptWithSymmetricKey(encryptedPackage, sessionKey);
139
+ console.log('Received:', decryptedData);
140
+
141
+ // C. Process data and prepare response
142
+ const responseData = { status: 'received', timestamp: Date.now() };
143
+
144
+ // D. Encrypt response using the SAME session key
145
+ const encryptedResponse = await encryptWithSymmetricKey(responseData, sessionKey);
146
+
147
+ res.writeHead(200, { 'Content-Type': 'application/json' });
148
+ res.end(JSON.stringify({ encryptedResponse }));
149
+ } catch (err) {
150
+ res.writeHead(500);
151
+ res.end(JSON.stringify({ error: err.message }));
152
+ }
153
+ });
154
+ }
155
+ });
156
+
157
+ server.listen(3000, () => console.log('Server running on port 3000'));
158
+ ```
159
+
160
+ ## Frontend Setup
161
+
162
+ This section demonstrates the client-side logic to establish a secure session.
163
+
164
+ ```javascript
165
+ import {
166
+ createSymmetricKey,
167
+ wrapKey,
168
+ encryptWithSymmetricKey,
169
+ decryptWithSymmetricKey
170
+ } from '@pulkitsinha007/hybrid-crypto-js';
171
+
172
+ async function sendSecureMessage(message) {
173
+ // 1. Fetch Server Public Key
174
+ const res = await fetch('http://localhost:3000/api/public-key');
175
+ const { publicKey } = await res.json();
176
+
177
+ // 2. Create a fresh Session Key (AES)
178
+ const sessionKey = await createSymmetricKey();
179
+
180
+ // 3. Wrap (Encrypt) the Session Key with Server's Public Key
181
+ const wrappedKey = await wrapKey(sessionKey, publicKey);
182
+
183
+ // 4. Encrypt the payload with the Session Key
184
+ const encryptedPackage = await encryptWithSymmetricKey(message, sessionKey);
185
+
186
+ // 5. Send both to the server
187
+ const postRes = await fetch('http://localhost:3000/api/submit', {
188
+ method: 'POST',
189
+ body: JSON.stringify({
190
+ wrappedKey,
191
+ encryptedPackage
192
+ })
193
+ });
194
+
195
+ // 6. Receive and Decrypt Response (using the same Session Key)
196
+ const { encryptedResponse } = await postRes.json();
197
+ const responseData = await decryptWithSymmetricKey(encryptedResponse, sessionKey);
198
+
199
+ console.log('Server Response:', responseData);
200
+ }
201
+
202
+ sendSecureMessage({ hello: "world" });
203
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pulkitsinha007/hybrid-crypto-js",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "description": "Hybrid encryption package using native crypto modules for Node and Browser",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
package/src/crypto.js CHANGED
@@ -176,36 +176,4 @@ export async function unwrapKey(wrappedKey, privateKey) {
176
176
  );
177
177
 
178
178
  return key;
179
- }
180
-
181
- /**
182
- * Encrypts data using hybrid encryption (Generates new AES key).
183
- * @param {string|object} data - The payload to encrypt.
184
- * @param {string} publicKey - The backend's public RSA key (Base64).
185
- * @returns {Promise<{encryptedData: string, encryptedKey: string, iv: string}>}
186
- */
187
- export async function encrypt(data, publicKey) {
188
- const aesKey = await createSymmetricKey();
189
- const { encryptedData, iv } = await encryptWithSymmetricKey(data, aesKey);
190
- const encryptedKey = await wrapKey(aesKey, publicKey); // Reusing wrapKey
191
-
192
- return {
193
- encryptedData,
194
- encryptedKey,
195
- iv
196
- };
197
- }
198
-
199
- /**
200
- * Decrypts data using hybrid encryption.
201
- * @param {object} encryptedPackage - The encrypted package { encryptedData, encryptedKey, iv }.
202
- * @param {string} privateKey - The backend's private RSA key (Base64).
203
- * @returns {Promise<string|object>} The decrypted payload.
204
- */
205
- export async function decrypt(encryptedPackage, privateKey) {
206
- const { encryptedData, encryptedKey, iv } = encryptedPackage;
207
-
208
- const aesKey = await unwrapKey(encryptedKey, privateKey); // Reusing unwrapKey
209
-
210
- return await decryptWithSymmetricKey({ encryptedData, iv }, aesKey);
211
- }
179
+ }
package/src/index.d.ts CHANGED
@@ -91,27 +91,4 @@ export function wrapKey(key: CryptoKey, publicKey: string): Promise<string>;
91
91
  * @param privateKey - The RSA private key (Base64).
92
92
  * @returns The unwrapped AES key.
93
93
  */
94
- export function unwrapKey(wrappedKey: string, privateKey: string): Promise<CryptoKey>;
95
-
96
- /**
97
- * Encrypts data using hybrid encryption (Generates new AES key).
98
- * @param data - The payload to encrypt.
99
- * @param publicKey - The backend's public RSA key (Base64).
100
- */
101
- export function encrypt(data: string | object, publicKey: string): Promise<{
102
- encryptedData: string;
103
- encryptedKey: string;
104
- iv: string;
105
- }>;
106
-
107
- /**
108
- * Decrypts data using hybrid encryption.
109
- * @param encryptedPackage - The encrypted package { encryptedData, encryptedKey, iv }.
110
- * @param privateKey - The backend's private RSA key (Base64).
111
- * @returns The decrypted payload.
112
- */
113
- export function decrypt<T = any>(encryptedPackage: {
114
- encryptedData: string;
115
- encryptedKey: string;
116
- iv: string;
117
- }, privateKey: string): Promise<T>;
94
+ export function unwrapKey(wrappedKey: string, privateKey: string): Promise<CryptoKey>;
package/src/index.js CHANGED
@@ -1,7 +1,5 @@
1
1
  export {
2
2
  generateKeyPair,
3
- encrypt,
4
- decrypt,
5
3
  createSymmetricKey,
6
4
  encryptWithSymmetricKey,
7
5
  decryptWithSymmetricKey,
package/src/utils.js CHANGED
@@ -1,77 +1,77 @@
1
- // Utility functions for Hybrid Crypto Package
2
-
3
- /**
4
- * Converts a string to an ArrayBuffer using TextEncoder.
5
- * @param {string} str - The string to convert.
6
- * @returns {ArrayBuffer} The resulting ArrayBuffer.
7
- */
8
- export function str2ab(str) {
9
- return new TextEncoder().encode(str);
10
- }
11
-
12
- /**
13
- * Converts an ArrayBuffer to a string using TextDecoder.
14
- * @param {ArrayBuffer} buf - The buffer to convert.
15
- * @returns {string} The resulting string.
16
- */
17
- export function ab2str(buf) {
18
- return new TextDecoder().decode(buf);
19
- }
20
-
21
- /**
22
- * Converts an ArrayBuffer to a Base64 string.
23
- * @param {ArrayBuffer} buf - The buffer to convert.
24
- * @returns {string} Base64 string.
25
- */
26
- export function arrayBufferToBase64(buf) {
27
- let binary = '';
28
- const bytes = new Uint8Array(buf);
29
- const len = bytes.byteLength;
30
- for (let i = 0; i < len; i++) {
31
- binary += String.fromCharCode(bytes[i]);
32
- }
33
- return btoa(binary);
34
- }
35
-
36
- /**
37
- * Converts a Base64 string to an ArrayBuffer.
38
- * @param {string} base64 - The Base64 string.
39
- * @returns {ArrayBuffer} The resulting ArrayBuffer.
40
- */
41
- export function base64ToArrayBuffer(base64) {
42
- const binaryString = atob(base64);
43
- const len = binaryString.length;
44
- const bytes = new Uint8Array(len);
45
- for (let i = 0; i < len; i++) {
46
- bytes[i] = binaryString.charCodeAt(i);
47
- }
48
- return bytes.buffer;
49
- }
50
-
51
- /**
52
- * Converts a PEM formatted string to an ArrayBuffer.
53
- * @param {string} pem - The PEM string.
54
- * @returns {ArrayBuffer} The raw key data.
55
- */
56
- export function pemToArrayBuffer(pem) {
57
- // Remove headers, footers, and newlines
58
- const b64 = pem
59
- .replace(/-----BEGIN [^-]+-----/, '')
60
- .replace(/-----END [^-]+-----/, '')
61
- .replace(/\s/g, ''); // Removes all whitespace including newlines
62
- return base64ToArrayBuffer(b64);
63
- }
64
-
65
- /**
66
- * Converts an ArrayBuffer to a PEM formatted string.
67
- * @param {ArrayBuffer} buf - The raw key data.
68
- * @param {string} type - The key type (e.g., 'PUBLIC KEY', 'PRIVATE KEY').
69
- * @returns {string} The PEM string.
70
- */
71
- export function arrayBufferToPem(buf, type) {
72
- const b64 = arrayBufferToBase64(buf);
73
- const pemString = `-----BEGIN ${type}-----\n` +
74
- b64.match(/.{1,64}/g).join('\n') +
75
- `\n-----END ${type}-----\n`;
76
- return pemString;
77
- }
1
+ // Utility functions for Hybrid Crypto Package
2
+
3
+ /**
4
+ * Converts a string to an ArrayBuffer using TextEncoder.
5
+ * @param {string} str - The string to convert.
6
+ * @returns {ArrayBuffer} The resulting ArrayBuffer.
7
+ */
8
+ export function str2ab(str) {
9
+ return new TextEncoder().encode(str);
10
+ }
11
+
12
+ /**
13
+ * Converts an ArrayBuffer to a string using TextDecoder.
14
+ * @param {ArrayBuffer} buf - The buffer to convert.
15
+ * @returns {string} The resulting string.
16
+ */
17
+ export function ab2str(buf) {
18
+ return new TextDecoder().decode(buf);
19
+ }
20
+
21
+ /**
22
+ * Converts an ArrayBuffer to a Base64 string.
23
+ * @param {ArrayBuffer} buf - The buffer to convert.
24
+ * @returns {string} Base64 string.
25
+ */
26
+ export function arrayBufferToBase64(buf) {
27
+ let binary = '';
28
+ const bytes = new Uint8Array(buf);
29
+ const len = bytes.byteLength;
30
+ for (let i = 0; i < len; i++) {
31
+ binary += String.fromCharCode(bytes[i]);
32
+ }
33
+ return btoa(binary);
34
+ }
35
+
36
+ /**
37
+ * Converts a Base64 string to an ArrayBuffer.
38
+ * @param {string} base64 - The Base64 string.
39
+ * @returns {ArrayBuffer} The resulting ArrayBuffer.
40
+ */
41
+ export function base64ToArrayBuffer(base64) {
42
+ const binaryString = atob(base64);
43
+ const len = binaryString.length;
44
+ const bytes = new Uint8Array(len);
45
+ for (let i = 0; i < len; i++) {
46
+ bytes[i] = binaryString.charCodeAt(i);
47
+ }
48
+ return bytes.buffer;
49
+ }
50
+
51
+ /**
52
+ * Converts a PEM formatted string to an ArrayBuffer.
53
+ * @param {string} pem - The PEM string.
54
+ * @returns {ArrayBuffer} The raw key data.
55
+ */
56
+ export function pemToArrayBuffer(pem) {
57
+ // Remove headers, footers, and newlines
58
+ const b64 = pem
59
+ .replace(/-----BEGIN [^-]+-----/, '')
60
+ .replace(/-----END [^-]+-----/, '')
61
+ .replace(/\s/g, ''); // Removes all whitespace including newlines
62
+ return base64ToArrayBuffer(b64);
63
+ }
64
+
65
+ /**
66
+ * Converts an ArrayBuffer to a PEM formatted string.
67
+ * @param {ArrayBuffer} buf - The raw key data.
68
+ * @param {string} type - The key type (e.g., 'PUBLIC KEY', 'PRIVATE KEY').
69
+ * @returns {string} The PEM string.
70
+ */
71
+ export function arrayBufferToPem(buf, type) {
72
+ const b64 = arrayBufferToBase64(buf);
73
+ const pemString = `-----BEGIN ${type}-----\n` +
74
+ b64.match(/.{1,64}/g).join('\n') +
75
+ `\n-----END ${type}-----\n`;
76
+ return pemString;
77
+ }