@ubay182/sveltekit-hpke-wrapper 1.0.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/README.md ADDED
@@ -0,0 +1,279 @@
1
+ # @hpke/sveltekit-wrapper
2
+
3
+ HPKE (Hybrid Public Key Encryption) wrapper for SvelteKit applications with end-to-end encryption support.
4
+
5
+ ## 🚀 Features
6
+
7
+ - ✅ **Complete HPKE Implementation** - RFC 9180 compliant
8
+ - ✅ **End-to-End Encryption** - Client ↔ Server encryption
9
+ - ✅ **SvelteKit Integration** - Ready-to-use API endpoint creators
10
+ - ✅ **TypeScript Support** - Full type definitions
11
+ - ✅ **X25519 Key Exchange** - Elliptic curve Diffie-Hellman
12
+ - ✅ **AES-128-GCM & ChaCha20** - Authenticated encryption
13
+
14
+ ## 📦 Installation
15
+
16
+ ```bash
17
+ npm install @hpke/sveltekit-wrapper
18
+ # or
19
+ pnpm add @hpke/sveltekit-wrapper
20
+ # or
21
+ yarn add @hpke/sveltekit-wrapper
22
+ ```
23
+
24
+ ## 🎯 Quick Start
25
+
26
+ ### 1. Basic Usage (Client-Side)
27
+
28
+ ```typescript
29
+ import {
30
+ generateKeyPair,
31
+ hpkeEncrypt,
32
+ hpkeDecrypt,
33
+ exportKeyToBase64,
34
+ importKeyFromBase64
35
+ } from '@hpke/sveltekit-wrapper';
36
+
37
+ // Generate key pair
38
+ const { publicKey, privateKey, publicKeyRaw } = await generateKeyPair();
39
+
40
+ // Export public key for transmission
41
+ const publicKeyBase64 = exportKeyToBase64(publicKey);
42
+
43
+ // Import server's public key
44
+ const serverPublicKey = await importKeyFromBase64(serverPublicKeyBase64);
45
+
46
+ // Encrypt message
47
+ const { ciphertext, enc } = await hpkeEncrypt('Secret message', serverPublicKey);
48
+
49
+ // Decrypt message
50
+ const decrypted = await hpkeDecrypt(ciphertext, enc, privateKey);
51
+ ```
52
+
53
+ ### 2. Server-Side with SvelteKit
54
+
55
+ ```typescript
56
+ // src/routes/api/hpke/+server.ts
57
+ import { createHpkeEndpoint } from '@hpke/sveltekit-wrapper';
58
+
59
+ const { GET, POST } = createHpkeEndpoint({
60
+ onRequest: async (decryptedData, request) => {
61
+ // Process the decrypted request
62
+ const response = await fetch('https://api.example.com/data', {
63
+ method: 'POST',
64
+ headers: { 'Content-Type': 'application/json' },
65
+ body: JSON.stringify(decryptedData)
66
+ });
67
+
68
+ return await response.json();
69
+ }
70
+ });
71
+
72
+ export { GET, POST };
73
+ ```
74
+
75
+ ### 3. Manual Server Setup
76
+
77
+ ```typescript
78
+ import { createHpkeServer } from '@hpke/sveltekit-wrapper';
79
+
80
+ const server = createHpkeServer();
81
+
82
+ // Get server public key
83
+ const publicKey = server.getPublicKeyBase64();
84
+
85
+ // Decrypt client message
86
+ const decrypted = await server.decrypt(ciphertext, enc, clientPublicKey);
87
+
88
+ // Encrypt response
89
+ const encrypted = await server.encrypt(responseData, clientPublicKey);
90
+ ```
91
+
92
+ ## 📚 API Reference
93
+
94
+ ### Core Functions
95
+
96
+ #### `generateKeyPair()`
97
+ Generate a new HPKE key pair.
98
+
99
+ ```typescript
100
+ async function generateKeyPair(): Promise<{
101
+ publicKey: any; // XCryptoKey for HPKE operations
102
+ privateKey: any; // XCryptoKey for HPKE operations
103
+ publicKeyRaw: Uint8Array; // Raw bytes for transmission
104
+ }>
105
+ ```
106
+
107
+ #### `hpkeEncrypt(message, recipientPublicKey)`
108
+ Encrypt a message.
109
+
110
+ ```typescript
111
+ async function hpkeEncrypt(
112
+ message: string,
113
+ recipientPublicKey: any
114
+ ): Promise<{
115
+ ciphertext: ArrayBuffer;
116
+ enc: ArrayBuffer;
117
+ }>
118
+ ```
119
+
120
+ #### `hpkeDecrypt(ciphertext, enc, recipientPrivateKey)`
121
+ Decrypt a message.
122
+
123
+ ```typescript
124
+ async function hpkeDecrypt(
125
+ ciphertext: ArrayBuffer,
126
+ enc: Uint8Array | ArrayBuffer,
127
+ recipientPrivateKey: any
128
+ ): Promise<string>
129
+ ```
130
+
131
+ #### `exportKeyToBase64(publicKey)`
132
+ Export public key to base64.
133
+
134
+ ```typescript
135
+ function exportKeyToBase64(publicKey: any): string
136
+ ```
137
+
138
+ #### `importKeyFromBase64(base64)`
139
+ Import public key from base64.
140
+
141
+ ```typescript
142
+ async function importKeyFromBase64(base64: string): Promise<any>
143
+ ```
144
+
145
+ ### Server Functions
146
+
147
+ #### `createHpkeServer(config?)`
148
+ Create HPKE server instance.
149
+
150
+ ```typescript
151
+ interface HpkeServerConfig {
152
+ autoGenerateKeys?: boolean; // Default: true
153
+ }
154
+
155
+ interface HpkeServerInstance {
156
+ getPublicKeyBase64(): string;
157
+ decrypt(ciphertext: string, enc: string, clientPublicKey: string): Promise<string>;
158
+ encrypt(message: string, clientPublicKey: string): Promise<{
159
+ ciphertext: string;
160
+ enc: string;
161
+ }>;
162
+ }
163
+ ```
164
+
165
+ ### SvelteKit Integration
166
+
167
+ #### `createHpkeEndpoint(config?)`
168
+ Create complete API endpoints.
169
+
170
+ ```typescript
171
+ interface HpkeEndpointConfig {
172
+ autoGenerateKeys?: boolean;
173
+ onRequest?: (decrypted: any, request: Request) => Promise<any>;
174
+ onError?: (error: Error, request: Request) => Promise<Response>;
175
+ }
176
+ ```
177
+
178
+ ## 🔧 Advanced Usage
179
+
180
+ ### Custom Algorithm (ChaCha20-Poly1305)
181
+
182
+ ```typescript
183
+ import { createHpkeSuiteChaCha20 } from '@hpke/sveltekit-wrapper';
184
+
185
+ const suite = createHpkeSuiteChaCha20();
186
+ // Use suite for encryption/decryption
187
+ ```
188
+
189
+ ### Manual Key Management
190
+
191
+ ```typescript
192
+ import { createHpkeServer } from '@hpke/sveltekit-wrapper';
193
+
194
+ // Disable auto-generation
195
+ const server = createHpkeServer({ autoGenerateKeys: false });
196
+
197
+ // Set keys manually later
198
+ // (You'll need to extend the server instance with a setKeys method)
199
+ ```
200
+
201
+ ### Error Handling
202
+
203
+ ```typescript
204
+ const { GET, POST } = createHpkeEndpoint({
205
+ onError: async (error, request) => {
206
+ console.error('HPKE Error:', error);
207
+
208
+ return new Response(
209
+ JSON.stringify({
210
+ error: 'Encryption failed',
211
+ code: 'HPKE_ERROR'
212
+ }),
213
+ { status: 500 }
214
+ );
215
+ }
216
+ });
217
+ ```
218
+
219
+ ## 🔐 Security Notes
220
+
221
+ ⚠️ **Important**: This is a wrapper library for convenience. For production:
222
+
223
+ 1. **Key Storage**: Use HSM, AWS KMS, or Azure Key Vault
224
+ 2. **HTTPS**: Always use HTTPS in production
225
+ 3. **Authentication**: Implement proper auth mechanisms
226
+ 4. **Rate Limiting**: Add rate limiting to prevent abuse
227
+ 5. **Key Rotation**: Implement regular key rotation
228
+ 6. **Audit**: Have security audits performed
229
+
230
+ ## 📖 How It Works
231
+
232
+ ```
233
+ Client Server
234
+ │ │
235
+ ├─── GET /api/hpke ───────────>│
236
+ │ │
237
+ │<──── Public Key (base64) ────│
238
+ │ │
239
+ ├─── Encrypt with Public Key ──│
240
+ │ │
241
+ ├─── POST Encrypted Data ─────>│
242
+ │ │
243
+ │ ├─── Decrypt ──┐
244
+ │ │ │
245
+ │ │<── Process ───┘
246
+ │ │
247
+ │ ├─── Encrypt ──┐
248
+ │ │ │
249
+ │<──── Encrypted Response ─────│<──────────────┘
250
+ │ │
251
+ └─── Decrypt Response ─────────┘
252
+ ```
253
+
254
+ ## 🧪 Testing
255
+
256
+ ```bash
257
+ # Build the package
258
+ npm run build
259
+
260
+ # Type check
261
+ npm run lint
262
+
263
+ # Watch mode for development
264
+ npm run dev
265
+ ```
266
+
267
+ ## 📄 License
268
+
269
+ MIT
270
+
271
+ ## 🤝 Contributing
272
+
273
+ Contributions are welcome! Please feel free to submit a Pull Request.
274
+
275
+ ## 📚 Resources
276
+
277
+ - [RFC 9180 - HPKE Specification](https://www.rfc-editor.org/rfc/rfc9180.html)
278
+ - [hpke-js Library](https://github.com/dajiaji/hpke-js)
279
+ - [SvelteKit Documentation](https://kit.svelte.dev/docs)
package/dist/hpke.d.ts ADDED
@@ -0,0 +1,140 @@
1
+ import { CipherSuite } from '@hpke/core';
2
+ /**
3
+ * HPKE Key Pair type (using HPKE library's XCryptoKey)
4
+ */
5
+ export interface HpkeKeyPair {
6
+ publicKey: any;
7
+ privateKey: any;
8
+ publicKeyRaw: Uint8Array;
9
+ }
10
+ /**
11
+ * Encrypted message structure
12
+ */
13
+ export interface HpkeEncryptedMessage {
14
+ ciphertext: ArrayBuffer;
15
+ enc: ArrayBuffer;
16
+ }
17
+ /**
18
+ * HPKE Suite configuration
19
+ */
20
+ export interface HpkeSuiteConfig {
21
+ kem?: 'X25519';
22
+ kdf?: 'HKDF-SHA256';
23
+ aead?: 'AES-128-GCM' | 'ChaCha20-Poly1305';
24
+ }
25
+ /**
26
+ * Create HPKE Suite with AES-128-GCM
27
+ *
28
+ * @returns Configured CipherSuite instance
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * const suite = createHpkeSuite();
33
+ * const keyPair = await suite.kem.generateKeyPair();
34
+ * ```
35
+ */
36
+ export declare function createHpkeSuite(): CipherSuite;
37
+ /**
38
+ * Create HPKE Suite with ChaCha20-Poly1305
39
+ *
40
+ * @returns Configured CipherSuite instance
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * const suite = createHpkeSuiteChaCha20();
45
+ * ```
46
+ */
47
+ export declare function createHpkeSuiteChaCha20(): CipherSuite;
48
+ /**
49
+ * Generate a new HPKE key pair
50
+ *
51
+ * @returns Key pair with XCryptoKey objects and raw public key bytes
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * const { publicKey, privateKey, publicKeyRaw } = await generateKeyPair();
56
+ * ```
57
+ */
58
+ export declare function generateKeyPair(): Promise<HpkeKeyPair>;
59
+ /**
60
+ * Export HPKE public key to base64 string
61
+ *
62
+ * @param publicKey - HPKE public key (XCryptoKey)
63
+ * @returns Base64 encoded public key
64
+ *
65
+ * @example
66
+ * ```typescript
67
+ * const base64 = exportKeyToBase64(publicKey);
68
+ * ```
69
+ */
70
+ export declare function exportKeyToBase64(publicKey: any): string;
71
+ /**
72
+ * Import HPKE public key from base64 string
73
+ *
74
+ * @param base64 - Base64 encoded public key
75
+ * @returns HPKE public key (XCryptoKey)
76
+ *
77
+ * @example
78
+ * ```typescript
79
+ * const publicKey = await importKeyFromBase64(base64String);
80
+ * ```
81
+ */
82
+ export declare function importKeyFromBase64(base64: string): Promise<any>;
83
+ /**
84
+ * Encrypt a message using HPKE
85
+ *
86
+ * @param message - Plaintext message to encrypt
87
+ * @param recipientPublicKey - Recipient's public key (XCryptoKey)
88
+ * @returns Encrypted message with ciphertext and encapsulated key
89
+ *
90
+ * @example
91
+ * ```typescript
92
+ * const { ciphertext, enc } = await hpkeEncrypt('Secret message', publicKey);
93
+ * ```
94
+ */
95
+ export declare function hpkeEncrypt(message: string, recipientPublicKey: any): Promise<HpkeEncryptedMessage>;
96
+ /**
97
+ * Decrypt a message using HPKE
98
+ *
99
+ * @param ciphertext - Encrypted ciphertext (ArrayBuffer)
100
+ * @param enc - Encapsulated key (Uint8Array or ArrayBuffer)
101
+ * @param recipientPrivateKey - Recipient's private key (XCryptoKey)
102
+ * @returns Decrypted plaintext message
103
+ *
104
+ * @example
105
+ * ```typescript
106
+ * const decrypted = await hpkeDecrypt(ciphertext, enc, privateKey);
107
+ * ```
108
+ */
109
+ export declare function hpkeDecrypt(ciphertext: ArrayBuffer, enc: Uint8Array | ArrayBuffer, recipientPrivateKey: any): Promise<string>;
110
+ /**
111
+ * Complete encryption/decryption demo
112
+ *
113
+ * @returns Demo result with original and decrypted messages
114
+ *
115
+ * @example
116
+ * ```typescript
117
+ * const result = await hpkeDemo();
118
+ * console.log(result.match); // true
119
+ * ```
120
+ */
121
+ export declare function hpkeDemo(): Promise<{
122
+ original: string;
123
+ decrypted: string;
124
+ match: boolean;
125
+ }>;
126
+ /**
127
+ * Convert Uint8Array to base64 string
128
+ *
129
+ * @param data - Uint8Array to convert
130
+ * @returns Base64 encoded string
131
+ */
132
+ export declare function uint8ArrayToBase64(data: Uint8Array): string;
133
+ /**
134
+ * Convert base64 string to Uint8Array
135
+ *
136
+ * @param base64 - Base64 encoded string
137
+ * @returns Uint8Array
138
+ */
139
+ export declare function base64ToUint8Array(base64: string): Uint8Array;
140
+ //# sourceMappingURL=hpke.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hpke.d.ts","sourceRoot":"","sources":["../src/hpke.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAKzC;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,SAAS,EAAE,GAAG,CAAC;IACf,UAAU,EAAE,GAAG,CAAC;IAChB,YAAY,EAAE,UAAU,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC,UAAU,EAAE,WAAW,CAAC;IACxB,GAAG,EAAE,WAAW,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf,GAAG,CAAC,EAAE,aAAa,CAAC;IACpB,IAAI,CAAC,EAAE,aAAa,GAAG,mBAAmB,CAAC;CAC3C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,gBAM9B;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,gBAMtC;AAED;;;;;;;;;GASG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,WAAW,CAAC,CAY5D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,GAAG,GAAG,MAAM,CAGxD;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAItE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,WAAW,CAChC,OAAO,EAAE,MAAM,EACf,kBAAkB,EAAE,GAAG,GACrB,OAAO,CAAC,oBAAoB,CAAC,CAc/B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,WAAW,CAChC,UAAU,EAAE,WAAW,EACvB,GAAG,EAAE,UAAU,GAAG,WAAW,EAC7B,mBAAmB,EAAE,GAAG,GACtB,OAAO,CAAC,MAAM,CAAC,CAcjB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,QAAQ;;;;GAY7B;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAM3D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAO7D"}
package/dist/hpke.js ADDED
@@ -0,0 +1,190 @@
1
+ import { CipherSuite } from '@hpke/core';
2
+ import { DhkemX25519HkdfSha256 } from '@hpke/dhkem-x25519';
3
+ import { HkdfSha256, Aes128Gcm } from '@hpke/core';
4
+ import { Chacha20Poly1305 } from '@hpke/chacha20poly1305';
5
+ /**
6
+ * Create HPKE Suite with AES-128-GCM
7
+ *
8
+ * @returns Configured CipherSuite instance
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * const suite = createHpkeSuite();
13
+ * const keyPair = await suite.kem.generateKeyPair();
14
+ * ```
15
+ */
16
+ export function createHpkeSuite() {
17
+ return new CipherSuite({
18
+ kem: new DhkemX25519HkdfSha256(),
19
+ kdf: new HkdfSha256(),
20
+ aead: new Aes128Gcm(),
21
+ });
22
+ }
23
+ /**
24
+ * Create HPKE Suite with ChaCha20-Poly1305
25
+ *
26
+ * @returns Configured CipherSuite instance
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * const suite = createHpkeSuiteChaCha20();
31
+ * ```
32
+ */
33
+ export function createHpkeSuiteChaCha20() {
34
+ return new CipherSuite({
35
+ kem: new DhkemX25519HkdfSha256(),
36
+ kdf: new HkdfSha256(),
37
+ aead: new Chacha20Poly1305(),
38
+ });
39
+ }
40
+ /**
41
+ * Generate a new HPKE key pair
42
+ *
43
+ * @returns Key pair with XCryptoKey objects and raw public key bytes
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * const { publicKey, privateKey, publicKeyRaw } = await generateKeyPair();
48
+ * ```
49
+ */
50
+ export async function generateKeyPair() {
51
+ const suite = createHpkeSuite();
52
+ const keyPair = await suite.kem.generateKeyPair();
53
+ // Export public key as raw bytes for transmission
54
+ const publicKeyRaw = new Uint8Array(Object.values(keyPair.publicKey.key));
55
+ return {
56
+ publicKey: keyPair.publicKey,
57
+ privateKey: keyPair.privateKey,
58
+ publicKeyRaw,
59
+ };
60
+ }
61
+ /**
62
+ * Export HPKE public key to base64 string
63
+ *
64
+ * @param publicKey - HPKE public key (XCryptoKey)
65
+ * @returns Base64 encoded public key
66
+ *
67
+ * @example
68
+ * ```typescript
69
+ * const base64 = exportKeyToBase64(publicKey);
70
+ * ```
71
+ */
72
+ export function exportKeyToBase64(publicKey) {
73
+ const publicKeyRaw = new Uint8Array(Object.values(publicKey.key));
74
+ return uint8ArrayToBase64(publicKeyRaw);
75
+ }
76
+ /**
77
+ * Import HPKE public key from base64 string
78
+ *
79
+ * @param base64 - Base64 encoded public key
80
+ * @returns HPKE public key (XCryptoKey)
81
+ *
82
+ * @example
83
+ * ```typescript
84
+ * const publicKey = await importKeyFromBase64(base64String);
85
+ * ```
86
+ */
87
+ export async function importKeyFromBase64(base64) {
88
+ const keyBytes = base64ToUint8Array(base64);
89
+ const suite = createHpkeSuite();
90
+ return await suite.kem.importKey('raw', keyBytes.buffer, true);
91
+ }
92
+ /**
93
+ * Encrypt a message using HPKE
94
+ *
95
+ * @param message - Plaintext message to encrypt
96
+ * @param recipientPublicKey - Recipient's public key (XCryptoKey)
97
+ * @returns Encrypted message with ciphertext and encapsulated key
98
+ *
99
+ * @example
100
+ * ```typescript
101
+ * const { ciphertext, enc } = await hpkeEncrypt('Secret message', publicKey);
102
+ * ```
103
+ */
104
+ export async function hpkeEncrypt(message, recipientPublicKey) {
105
+ const suite = createHpkeSuite();
106
+ const sender = await suite.createSenderContext({
107
+ recipientPublicKey,
108
+ });
109
+ const encoded = new TextEncoder().encode(message);
110
+ const ciphertext = await sender.seal(encoded);
111
+ return {
112
+ ciphertext,
113
+ enc: sender.enc,
114
+ };
115
+ }
116
+ /**
117
+ * Decrypt a message using HPKE
118
+ *
119
+ * @param ciphertext - Encrypted ciphertext (ArrayBuffer)
120
+ * @param enc - Encapsulated key (Uint8Array or ArrayBuffer)
121
+ * @param recipientPrivateKey - Recipient's private key (XCryptoKey)
122
+ * @returns Decrypted plaintext message
123
+ *
124
+ * @example
125
+ * ```typescript
126
+ * const decrypted = await hpkeDecrypt(ciphertext, enc, privateKey);
127
+ * ```
128
+ */
129
+ export async function hpkeDecrypt(ciphertext, enc, recipientPrivateKey) {
130
+ const suite = createHpkeSuite();
131
+ // Convert enc to Uint8Array if it's ArrayBuffer
132
+ const encBytes = enc instanceof Uint8Array ? enc : new Uint8Array(enc);
133
+ const ciphertextBytes = new Uint8Array(ciphertext);
134
+ const recipient = await suite.createRecipientContext({
135
+ recipientKey: recipientPrivateKey,
136
+ enc: encBytes,
137
+ });
138
+ const plaintext = await recipient.open(ciphertextBytes.buffer);
139
+ return new TextDecoder().decode(plaintext);
140
+ }
141
+ /**
142
+ * Complete encryption/decryption demo
143
+ *
144
+ * @returns Demo result with original and decrypted messages
145
+ *
146
+ * @example
147
+ * ```typescript
148
+ * const result = await hpkeDemo();
149
+ * console.log(result.match); // true
150
+ * ```
151
+ */
152
+ export async function hpkeDemo() {
153
+ const { publicKey, privateKey } = await generateKeyPair();
154
+ const message = 'Hello HPKE!';
155
+ const { ciphertext, enc } = await hpkeEncrypt(message, publicKey);
156
+ const decrypted = await hpkeDecrypt(ciphertext, enc, privateKey);
157
+ return {
158
+ original: message,
159
+ decrypted,
160
+ match: message === decrypted,
161
+ };
162
+ }
163
+ /**
164
+ * Convert Uint8Array to base64 string
165
+ *
166
+ * @param data - Uint8Array to convert
167
+ * @returns Base64 encoded string
168
+ */
169
+ export function uint8ArrayToBase64(data) {
170
+ let binary = '';
171
+ data.forEach((byte) => {
172
+ binary += String.fromCharCode(byte);
173
+ });
174
+ return btoa(binary);
175
+ }
176
+ /**
177
+ * Convert base64 string to Uint8Array
178
+ *
179
+ * @param base64 - Base64 encoded string
180
+ * @returns Uint8Array
181
+ */
182
+ export function base64ToUint8Array(base64) {
183
+ const binary = atob(base64);
184
+ const bytes = new Uint8Array(binary.length);
185
+ for (let i = 0; i < binary.length; i++) {
186
+ bytes[i] = binary.charCodeAt(i);
187
+ }
188
+ return bytes;
189
+ }
190
+ //# sourceMappingURL=hpke.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hpke.js","sourceRoot":"","sources":["../src/hpke.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * HPKE (Hybrid Public Key Encryption) Wrapper
3
+ *
4
+ * A complete HPKE implementation wrapper for SvelteKit applications
5
+ * providing end-to-end encryption between client and server.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ export { createHpkeSuite, createHpkeSuiteChaCha20, generateKeyPair, exportKeyToBase64, importKeyFromBase64, hpkeEncrypt, hpkeDecrypt, hpkeDemo, uint8ArrayToBase64, base64ToUint8Array, type HpkeKeyPair, type HpkeEncryptedMessage, type HpkeSuiteConfig, } from './hpke.js';
10
+ export { createHpkeServer, type HpkeServerInstance, type HpkeServerConfig, type HpkeRequestContext, type HpkeResponseContext, } from './server.js';
11
+ export { createHpkeEndpoint, type HpkeEndpointHandlers, type HpkeEndpointConfig, } from './sveltekit.js';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAEN,eAAe,EACf,uBAAuB,EAGvB,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EAGnB,WAAW,EACX,WAAW,EACX,QAAQ,EAGR,kBAAkB,EAClB,kBAAkB,EAGlB,KAAK,WAAW,EAChB,KAAK,oBAAoB,EACzB,KAAK,eAAe,GACpB,MAAM,WAAW,CAAC;AAGnB,OAAO,EACN,gBAAgB,EAChB,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,GACxB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACN,kBAAkB,EAClB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,GACvB,MAAM,gBAAgB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,23 @@
1
+ /**
2
+ * HPKE (Hybrid Public Key Encryption) Wrapper
3
+ *
4
+ * A complete HPKE implementation wrapper for SvelteKit applications
5
+ * providing end-to-end encryption between client and server.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ // Core HPKE functionality
10
+ export {
11
+ // HPKE Suite
12
+ createHpkeSuite, createHpkeSuiteChaCha20,
13
+ // Key Management
14
+ generateKeyPair, exportKeyToBase64, importKeyFromBase64,
15
+ // Encryption/Decryption
16
+ hpkeEncrypt, hpkeDecrypt, hpkeDemo,
17
+ // Utilities
18
+ uint8ArrayToBase64, base64ToUint8Array, } from './hpke.js';
19
+ // Server utilities
20
+ export { createHpkeServer, } from './server.js';
21
+ // SvelteKit helpers
22
+ export { createHpkeEndpoint, } from './sveltekit.js';
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,0BAA0B;AAC1B,OAAO;AACN,aAAa;AACb,eAAe,EACf,uBAAuB;AAEvB,iBAAiB;AACjB,eAAe,EACf,iBAAiB,EACjB,mBAAmB;AAEnB,wBAAwB;AACxB,WAAW,EACX,WAAW,EACX,QAAQ;AAER,YAAY;AACZ,kBAAkB,EAClB,kBAAkB,GAMlB,MAAM,WAAW,CAAC;AAEnB,mBAAmB;AACnB,OAAO,EACN,gBAAgB,GAKhB,MAAM,aAAa,CAAC;AAErB,oBAAoB;AACpB,OAAO,EACN,kBAAkB,GAGlB,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * HPKE Server instance with key management
3
+ */
4
+ export interface HpkeServerInstance {
5
+ /** Initialize server keys (call this first) */
6
+ init: () => Promise<string>;
7
+ /** Get server public key as base64 */
8
+ getPublicKeyBase64: () => string;
9
+ /** Decrypt message from client */
10
+ decrypt: (ciphertext: string, enc: string, clientPublicKey: string) => Promise<string>;
11
+ /** Encrypt message to client */
12
+ encrypt: (message: string, clientPublicKey: string) => Promise<{
13
+ ciphertext: string;
14
+ enc: string;
15
+ }>;
16
+ }
17
+ /**
18
+ * Server configuration options
19
+ */
20
+ export interface HpkeServerConfig {
21
+ /** Auto-generate keys on initialization (default: true) */
22
+ autoGenerateKeys?: boolean;
23
+ }
24
+ /**
25
+ * Request context for server-side processing
26
+ */
27
+ export interface HpkeRequestContext {
28
+ /** Encrypted ciphertext from client */
29
+ ciphertext: string;
30
+ /** Encapsulated key */
31
+ enc: string;
32
+ /** Client's public key */
33
+ clientPublicKey: string;
34
+ }
35
+ /**
36
+ * Response context for server-side encryption
37
+ */
38
+ export interface HpkeResponseContext {
39
+ /** Encrypted ciphertext */
40
+ ciphertext: string;
41
+ /** Encapsulated key */
42
+ enc: string;
43
+ }
44
+ /**
45
+ * Create HPKE server instance with key management
46
+ *
47
+ * @param config - Server configuration options
48
+ * @returns HpkeServerInstance with encryption/decryption methods
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * const server = createHpkeServer();
53
+ *
54
+ * // Initialize keys (async)
55
+ * const publicKey = await server.init();
56
+ *
57
+ * // In your API endpoint:
58
+ * const decrypted = await server.decrypt(ciphertext, enc, clientPublicKey);
59
+ * const response = await server.encrypt(responseData, clientPublicKey);
60
+ * ```
61
+ */
62
+ export declare function createHpkeServer(config?: HpkeServerConfig): HpkeServerInstance;
63
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC,+CAA+C;IAC/C,IAAI,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5B,sCAAsC;IACtC,kBAAkB,EAAE,MAAM,MAAM,CAAC;IACjC,kCAAkC;IAClC,OAAO,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACvF,gCAAgC;IAChC,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpG;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAChC,2DAA2D;IAC3D,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC,uCAAuC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,uBAAuB;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,0BAA0B;IAC1B,eAAe,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IACnC,2BAA2B;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,uBAAuB;IACvB,GAAG,EAAE,MAAM,CAAC;CACZ;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,GAAE,gBAAqB,GAAG,kBAAkB,CA6GlF"}
package/dist/server.js ADDED
@@ -0,0 +1,107 @@
1
+ import { CipherSuite } from '@hpke/core';
2
+ import { DhkemX25519HkdfSha256 } from '@hpke/dhkem-x25519';
3
+ import { HkdfSha256, Aes128Gcm } from '@hpke/core';
4
+ import { generateKeyPair, base64ToUint8Array, uint8ArrayToBase64 } from './hpke.js';
5
+ /**
6
+ * Create HPKE server instance with key management
7
+ *
8
+ * @param config - Server configuration options
9
+ * @returns HpkeServerInstance with encryption/decryption methods
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * const server = createHpkeServer();
14
+ *
15
+ * // Initialize keys (async)
16
+ * const publicKey = await server.init();
17
+ *
18
+ * // In your API endpoint:
19
+ * const decrypted = await server.decrypt(ciphertext, enc, clientPublicKey);
20
+ * const response = await server.encrypt(responseData, clientPublicKey);
21
+ * ```
22
+ */
23
+ export function createHpkeServer(config = {}) {
24
+ const { autoGenerateKeys = true } = config;
25
+ let serverKeyPair = null;
26
+ const instance = {
27
+ /**
28
+ * Initialize server keys
29
+ */
30
+ async init() {
31
+ const keys = await generateKeyPair();
32
+ serverKeyPair = {
33
+ publicKey: keys.publicKey,
34
+ privateKey: keys.privateKey,
35
+ };
36
+ return instance.getPublicKeyBase64();
37
+ },
38
+ /**
39
+ * Get server public key as base64 string
40
+ */
41
+ getPublicKeyBase64() {
42
+ if (!serverKeyPair) {
43
+ throw new Error('Server keys not initialized. Call init() first.');
44
+ }
45
+ const publicKeyRaw = new Uint8Array(Object.values(serverKeyPair.publicKey.key));
46
+ return uint8ArrayToBase64(publicKeyRaw);
47
+ },
48
+ /**
49
+ * Decrypt message from client
50
+ *
51
+ * @param ciphertext - Base64 encoded ciphertext
52
+ * @param enc - Base64 encoded encapsulated key
53
+ * @param clientPublicKey - Base64 encoded client public key
54
+ * @returns Decrypted plaintext message
55
+ */
56
+ async decrypt(ciphertext, enc, _clientPublicKey) {
57
+ if (!serverKeyPair) {
58
+ throw new Error('Server keys not initialized. Call init() first.');
59
+ }
60
+ const suite = new CipherSuite({
61
+ kem: new DhkemX25519HkdfSha256(),
62
+ kdf: new HkdfSha256(),
63
+ aead: new Aes128Gcm(),
64
+ });
65
+ const ciphertextBytes = base64ToUint8Array(ciphertext);
66
+ const encBytes = base64ToUint8Array(enc);
67
+ const recipient = await suite.createRecipientContext({
68
+ recipientKey: serverKeyPair.privateKey,
69
+ enc: encBytes,
70
+ });
71
+ const plaintext = await recipient.open(ciphertextBytes.buffer);
72
+ return new TextDecoder().decode(plaintext);
73
+ },
74
+ /**
75
+ * Encrypt message to client
76
+ *
77
+ * @param message - Plaintext message to encrypt
78
+ * @param clientPublicKeyBase64 - Base64 encoded client public key
79
+ * @returns Encrypted message with base64 encoded ciphertext and enc
80
+ */
81
+ async encrypt(message, clientPublicKeyBase64) {
82
+ const suite = new CipherSuite({
83
+ kem: new DhkemX25519HkdfSha256(),
84
+ kdf: new HkdfSha256(),
85
+ aead: new Aes128Gcm(),
86
+ });
87
+ const clientKeyBytes = base64ToUint8Array(clientPublicKeyBase64);
88
+ const clientPublicKey = await suite.kem.importKey('raw', clientKeyBytes.buffer, true);
89
+ const sender = await suite.createSenderContext({
90
+ recipientPublicKey: clientPublicKey,
91
+ });
92
+ const encrypted = await sender.seal(new TextEncoder().encode(message));
93
+ return {
94
+ ciphertext: uint8ArrayToBase64(new Uint8Array(encrypted)),
95
+ enc: uint8ArrayToBase64(new Uint8Array(sender.enc)),
96
+ };
97
+ },
98
+ };
99
+ // Auto-generate keys if enabled
100
+ if (autoGenerateKeys) {
101
+ instance.init().catch(err => {
102
+ console.error('Failed to auto-initialize server keys:', err);
103
+ });
104
+ }
105
+ return instance;
106
+ }
107
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import type { RequestHandler } from '@sveltejs/kit';
2
+ import { type HpkeServerConfig } from './server.js';
3
+ /**
4
+ * HPKE Endpoint handlers
5
+ */
6
+ export interface HpkeEndpointHandlers {
7
+ /** GET handler - Returns server public key */
8
+ GET?: RequestHandler;
9
+ /** POST handler - Process encrypted requests */
10
+ POST?: RequestHandler;
11
+ }
12
+ /**
13
+ * HPKE Endpoint configuration
14
+ */
15
+ export interface HpkeEndpointConfig extends HpkeServerConfig {
16
+ /** Custom handler for decrypted requests */
17
+ onRequest?: (decrypted: any, request: Request) => Promise<any>;
18
+ /** Custom error handler */
19
+ onError?: (error: Error, request: Request) => Promise<Response>;
20
+ }
21
+ /**
22
+ * Create SvelteKit API endpoints for HPKE
23
+ *
24
+ * Generates both GET and POST handlers for a complete HPKE API.
25
+ *
26
+ * @param config - Endpoint configuration
27
+ * @returns Object with GET and POST request handlers
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * // src/routes/api/hpke/+server.ts
32
+ * import { createHpkeEndpoint } from '@hpke/sveltekit-wrapper';
33
+ *
34
+ * const { GET, POST } = createHpkeEndpoint({
35
+ * onRequest: async (decrypted) => {
36
+ * // Process decrypted request
37
+ * const response = await fetch('https://api.example.com/data', {
38
+ * method: 'POST',
39
+ * body: JSON.stringify(decrypted)
40
+ * });
41
+ * return await response.json();
42
+ * }
43
+ * });
44
+ *
45
+ * export { GET, POST };
46
+ * ```
47
+ */
48
+ export declare function createHpkeEndpoint(config?: HpkeEndpointConfig): HpkeEndpointHandlers;
49
+ //# sourceMappingURL=sveltekit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sveltekit.d.ts","sourceRoot":"","sources":["../src/sveltekit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAoB,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEtE;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC,8CAA8C;IAC9C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,gDAAgD;IAChD,IAAI,CAAC,EAAE,cAAc,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAmB,SAAQ,gBAAgB;IAC3D,4CAA4C;IAC5C,SAAS,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IAC/D,2BAA2B;IAC3B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;CAChE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,GAAE,kBAAuB,GAAG,oBAAoB,CAuGxF"}
@@ -0,0 +1,108 @@
1
+ import { createHpkeServer } from './server.js';
2
+ /**
3
+ * Create SvelteKit API endpoints for HPKE
4
+ *
5
+ * Generates both GET and POST handlers for a complete HPKE API.
6
+ *
7
+ * @param config - Endpoint configuration
8
+ * @returns Object with GET and POST request handlers
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * // src/routes/api/hpke/+server.ts
13
+ * import { createHpkeEndpoint } from '@hpke/sveltekit-wrapper';
14
+ *
15
+ * const { GET, POST } = createHpkeEndpoint({
16
+ * onRequest: async (decrypted) => {
17
+ * // Process decrypted request
18
+ * const response = await fetch('https://api.example.com/data', {
19
+ * method: 'POST',
20
+ * body: JSON.stringify(decrypted)
21
+ * });
22
+ * return await response.json();
23
+ * }
24
+ * });
25
+ *
26
+ * export { GET, POST };
27
+ * ```
28
+ */
29
+ export function createHpkeEndpoint(config = {}) {
30
+ const server = createHpkeServer(config);
31
+ const GET = async () => {
32
+ try {
33
+ const publicKey = server.getPublicKeyBase64();
34
+ return new Response(JSON.stringify({
35
+ publicKey,
36
+ algorithm: 'X25519-HKDF-SHA256',
37
+ aead: 'AES-128-GCM',
38
+ }), {
39
+ headers: {
40
+ 'Content-Type': 'application/json',
41
+ },
42
+ });
43
+ }
44
+ catch (error) {
45
+ return new Response(JSON.stringify({
46
+ error: 'Failed to generate keys',
47
+ details: error instanceof Error ? error.message : String(error),
48
+ }), {
49
+ status: 500,
50
+ headers: { 'Content-Type': 'application/json' },
51
+ });
52
+ }
53
+ };
54
+ const POST = async ({ request }) => {
55
+ try {
56
+ const body = await request.json();
57
+ const { ciphertext, enc, clientPublicKey } = body;
58
+ if (!ciphertext || !enc || !clientPublicKey) {
59
+ return new Response(JSON.stringify({ error: 'Missing required fields' }), {
60
+ status: 400,
61
+ headers: { 'Content-Type': 'application/json' },
62
+ });
63
+ }
64
+ // Decrypt client message
65
+ const decryptedMessage = await server.decrypt(ciphertext, enc, clientPublicKey);
66
+ // Parse decrypted message
67
+ let decryptedData;
68
+ try {
69
+ decryptedData = JSON.parse(decryptedMessage);
70
+ }
71
+ catch {
72
+ decryptedData = { message: decryptedMessage };
73
+ }
74
+ // Process with custom handler or return decrypted data
75
+ let responseData;
76
+ if (config.onRequest) {
77
+ responseData = await config.onRequest(decryptedData, request);
78
+ }
79
+ else {
80
+ responseData = {
81
+ success: true,
82
+ data: decryptedData,
83
+ message: 'Request processed successfully',
84
+ };
85
+ }
86
+ // Encrypt response
87
+ const encrypted = await server.encrypt(JSON.stringify(responseData), clientPublicKey);
88
+ return new Response(JSON.stringify(encrypted), {
89
+ headers: { 'Content-Type': 'application/json' },
90
+ });
91
+ }
92
+ catch (error) {
93
+ // Custom error handler or default
94
+ if (config.onError) {
95
+ return config.onError(error, request);
96
+ }
97
+ return new Response(JSON.stringify({
98
+ error: 'Failed to process request',
99
+ details: error instanceof Error ? error.message : String(error),
100
+ }), {
101
+ status: 500,
102
+ headers: { 'Content-Type': 'application/json' },
103
+ });
104
+ }
105
+ };
106
+ return { GET, POST };
107
+ }
108
+ //# sourceMappingURL=sveltekit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sveltekit.js","sourceRoot":"","sources":["../src/sveltekit.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@ubay182/sveltekit-hpke-wrapper",
3
+ "version": "1.0.1",
4
+ "description": "HPKE (Hybrid Public Key Encryption) wrapper for SvelteKit applications with end-to-end encryption support",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsc",
20
+ "dev": "tsc --watch",
21
+ "lint": "tsc --noEmit",
22
+ "prepublishOnly": "npm run build"
23
+ },
24
+ "keywords": [
25
+ "hpke",
26
+ "encryption",
27
+ "sveltekit",
28
+ "x25519",
29
+ "aes-gcm",
30
+ "end-to-end",
31
+ "cryptography"
32
+ ],
33
+ "author": "",
34
+ "license": "MIT",
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "https://github.com/ubay1/sveltekit-hpke-wrapper"
38
+ },
39
+ "dependencies": {
40
+ "@hpke/chacha20poly1305": "^1.8.0",
41
+ "@hpke/core": "^1.9.0",
42
+ "@hpke/dhkem-x25519": "^1.8.0"
43
+ },
44
+ "devDependencies": {
45
+ "tsx": "^4.21.0",
46
+ "typescript": "^5.9.3"
47
+ },
48
+ "peerDependencies": {
49
+ "svelte": "^4.0.0 || ^5.0.0"
50
+ },
51
+ "engines": {
52
+ "node": ">=16.0.0"
53
+ }
54
+ }