@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 +279 -0
- package/dist/hpke.d.ts +140 -0
- package/dist/hpke.d.ts.map +1 -0
- package/dist/hpke.js +190 -0
- package/dist/hpke.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +63 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +107 -0
- package/dist/server.js.map +1 -0
- package/dist/sveltekit.d.ts +49 -0
- package/dist/sveltekit.d.ts.map +1 -0
- package/dist/sveltekit.js +108 -0
- package/dist/sveltekit.js.map +1 -0
- package/package.json +54 -0
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
|
package/dist/hpke.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hpke.js","sourceRoot":"","sources":["../src/hpke.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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"}
|
package/dist/server.d.ts
ADDED
|
@@ -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
|
+
}
|