( cipher: CipherPayload, password: string, )
| 299 | } |
| 300 | |
| 301 | async function decryptToken( |
| 302 | cipher: CipherPayload, |
| 303 | password: string, |
| 304 | ): Promise<string> { |
| 305 | if (cipher.algorithm !== "SHA256-SALTED+A256GCM") { |
| 306 | throw new Error("Unsupported token cipher."); |
| 307 | } |
| 308 | const key = await aesKeyForPassword(password, cipher.salt); |
| 309 | const plaintext = await crypto.subtle.decrypt( |
| 310 | { name: "AES-GCM", iv: base64UrlBytes(cipher.iv) }, |
| 311 | key, |
| 312 | base64UrlBytes(cipher.ciphertext), |
| 313 | ); |
| 314 | return new TextDecoder().decode(plaintext); |
| 315 | } |
| 316 | |
| 317 | async function aesKeyForPassword( |
| 318 | password: string, |
no test coverage detected