-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdecrypt.ts
More file actions
48 lines (42 loc) · 1.61 KB
/
decrypt.ts
File metadata and controls
48 lines (42 loc) · 1.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import { asymmetricAlgorithm, ivLength, pubKeyLength, symmetricAlgorithm } from "./config.ts";
async function decrypt(privateJwkString: string, payload: Uint8Array<ArrayBuffer>) {
const privateJwk = JSON.parse(privateJwkString);
const recipientPrivateKey = await crypto.subtle.importKey(
"jwk",
privateJwk,
asymmetricAlgorithm,
false, // not extractable
["deriveKey"]
);
// 1. UNBUNDLE the blob using fixed offsets
const receivedEphemeralPubKeyRaw = payload.buffer.slice(0, pubKeyLength);
const receivedIv = payload.buffer.slice(pubKeyLength, pubKeyLength + ivLength);
const receivedCiphertext = payload.buffer.slice(pubKeyLength + ivLength);
// 2. Import the sender's ephemeral public key
const receivedEphemeralPubKey = await crypto.subtle.importKey(
"raw",
receivedEphemeralPubKeyRaw,
asymmetricAlgorithm,
false, // not extractable
[] // no key usages needed for the public key in derivation
);
// 3. Derive the exact same symmetric key using the recipient's private key and the sender's public key
const derivedSymmetricKey = await crypto.subtle.deriveKey(
{
name: "ECDH",
public: receivedEphemeralPubKey, // The received ephemeral public key
},
recipientPrivateKey, // The recipient's long-term private key
symmetricAlgorithm,
false, // not extractable
["decrypt"] // We only need to decrypt
);
// 4. Decrypt the payload using the derived key and extracted IV
const decryptedPayload = await crypto.subtle.decrypt(
{ name: symmetricAlgorithm.name, iv: receivedIv },
derivedSymmetricKey,
receivedCiphertext
);
return new Uint8Array(decryptedPayload);
}
export default decrypt;