Last active
July 29, 2023 08:44
-
-
Save MrEliasen/a137457f1e685a136ea36af70ed76225 to your computer and use it in GitHub Desktop.
Symmetric Encryption using window.crypto.subtle API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Read more about the API here: | |
// https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto | |
export type EncryptedPayload = { ciphertext: string, iv: string }; | |
const algorithm: string = "AES-GCM"; | |
const keyLength: number = 256; | |
const extractable: boolean = true; | |
const keyUsages: KeyUsage[] = ["encrypt", "decrypt"]; | |
export function byteArrayToBase64(byteArray: ArrayBuffer) { | |
return btoa(String.fromCharCode(...new Uint8Array(byteArray))); | |
} | |
export function base64ToByteArray(base64String: string): ArrayBuffer { | |
return Uint8Array.from(atob(base64String), char => char.charCodeAt(0)); | |
} | |
export function importKey(cryptoKey: string): Promise<CryptoKey> { | |
return window.crypto.subtle.importKey( | |
"raw", | |
base64ToByteArray(cryptoKey), | |
algorithm, | |
extractable, | |
keyUsages | |
); | |
} | |
export function generateKey(): Promise<CryptoKey> { | |
return window.crypto.subtle.generateKey( | |
{ | |
name: algorithm, | |
length: keyLength, | |
}, | |
extractable, | |
keyUsages | |
); | |
} | |
export async function encrypt(message: string, encryptionKey: CryptoKey): Promise<EncryptedPayload> { | |
const enc = new TextEncoder(); | |
const iv = window.crypto.getRandomValues(new Uint8Array(12)); | |
const ciphertext = await window.crypto.subtle.encrypt( | |
{ | |
name: algorithm, | |
iv: iv | |
}, | |
encryptionKey, | |
enc.encode(message) | |
); | |
return { | |
ciphertext: byteArrayToBase64(ciphertext), | |
iv: byteArrayToBase64(iv) | |
} | |
} | |
export async function decrypt(payload: EncryptedPayload, decryptionKey: CryptoKey): Promise<string> { | |
const dec = new TextDecoder(); | |
let decrypted = await window.crypto.subtle.decrypt( | |
{ | |
name: algorithm, | |
iv: base64ToByteArray(payload.iv) | |
}, | |
decryptionKey, | |
base64ToByteArray(payload.ciphertext), | |
); | |
return dec.decode(decrypted) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
a much more developed version can be found here: https://github.com/MrEliasen/sniksnak.chat