@@ -8,6 +8,41 @@ const html = fs
88 . readFileSync ( path . resolve ( __dirname , "./index.template.html" ) , "utf8" )
99 . replace ( "${TURNKEY_SIGNER_ENVIRONMENT}" , "prod" ) ;
1010
11+ /**
12+ * Mirror of the iframe's encryptWithPassphrase, used to verify round-trips in tests.
13+ * Kept here rather than exported from TKHQ to avoid exposing decrypt on the global
14+ * in production.
15+ */
16+ async function decryptWithPassphrase ( encryptedBuf , passphrase ) {
17+ const salt = encryptedBuf . slice ( 0 , 16 ) ;
18+ const iv = encryptedBuf . slice ( 16 , 28 ) ;
19+ const ciphertext = encryptedBuf . slice ( 28 ) ;
20+
21+ const keyMaterial = await crypto . webcrypto . subtle . importKey (
22+ "raw" ,
23+ new TextEncoder ( ) . encode ( passphrase . normalize ( "NFC" ) ) ,
24+ "PBKDF2" ,
25+ false ,
26+ [ "deriveBits" , "deriveKey" ]
27+ ) ;
28+
29+ const aesKey = await crypto . webcrypto . subtle . deriveKey (
30+ { name : "PBKDF2" , salt, iterations : 600000 , hash : "SHA-256" } ,
31+ keyMaterial ,
32+ { name : "AES-GCM" , length : 256 } ,
33+ false ,
34+ [ "decrypt" ]
35+ ) ;
36+
37+ const decrypted = await crypto . webcrypto . subtle . decrypt (
38+ { name : "AES-GCM" , iv } ,
39+ aesKey ,
40+ ciphertext
41+ ) ;
42+
43+ return new Uint8Array ( decrypted ) ;
44+ }
45+
1146let dom ;
1247let TKHQ ;
1348
@@ -475,7 +510,7 @@ describe("TKHQ", () => {
475510 const encrypted = await TKHQ . encryptWithPassphrase ( plaintext , passphrase ) ;
476511
477512 // Decrypt
478- const decrypted = await TKHQ . decryptWithPassphrase ( encrypted , passphrase ) ;
513+ const decrypted = await decryptWithPassphrase ( encrypted , passphrase ) ;
479514
480515 // Verify
481516 const decryptedText = new TextDecoder ( ) . decode ( decrypted ) ;
@@ -494,7 +529,7 @@ describe("TKHQ", () => {
494529
495530 // Attempting to decrypt with wrong passphrase should throw
496531 await expect (
497- TKHQ . decryptWithPassphrase ( encrypted , wrongPassphrase )
532+ decryptWithPassphrase ( encrypted , wrongPassphrase )
498533 ) . rejects . toThrow ( ) ;
499534 } ) ;
500535
@@ -511,8 +546,8 @@ describe("TKHQ", () => {
511546 ) ;
512547
513548 // But both should decrypt to the same plaintext
514- const decrypted1 = await TKHQ . decryptWithPassphrase ( encrypted1 , passphrase ) ;
515- const decrypted2 = await TKHQ . decryptWithPassphrase ( encrypted2 , passphrase ) ;
549+ const decrypted1 = await decryptWithPassphrase ( encrypted1 , passphrase ) ;
550+ const decrypted2 = await decryptWithPassphrase ( encrypted2 , passphrase ) ;
516551
517552 expect ( new TextDecoder ( ) . decode ( decrypted1 ) ) . toBe ( "same plaintext" ) ;
518553 expect ( new TextDecoder ( ) . decode ( decrypted2 ) ) . toBe ( "same plaintext" ) ;
@@ -547,7 +582,7 @@ describe("TKHQ", () => {
547582 ) ;
548583
549584 // Decrypt
550- const decrypted = await TKHQ . decryptWithPassphrase (
585+ const decrypted = await decryptWithPassphrase (
551586 encryptedFromBase64 ,
552587 passphrase
553588 ) ;
0 commit comments