Skip to content

Instantly share code, notes, and snippets.

@mattlockyer
Created April 20, 2019 14:47
Show Gist options
  • Save mattlockyer/29e2ffa8fafb07385c00fa365270e1c8 to your computer and use it in GitHub Desktop.
Save mattlockyer/29e2ffa8fafb07385c00fa365270e1c8 to your computer and use it in GitHub Desktop.
WebCrypto ECDH Encryption / Decryption Basic Example (without validation, authentication)
//functions
const qs = (sel) => document.querySelector(sel)
const dhParams = (public) => ({ name: "ECDH", namedCurve: "P-256", public })
const aesParams = (length, counter) => ({ name: "AES-CTR", length, counter })
const keyInt = async(key) => new Uint8Array(await crypto.subtle.exportKey('raw', key));
const derive = async() => await window.crypto.subtle.generateKey(dhParams(), true, ["deriveKey", "deriveBits"])
const deriveAES = async(publicKey, privateKey) => await window.crypto.subtle.deriveKey(
dhParams(publicKey), privateKey, aesParams(256), true, ["encrypt", "decrypt"]
)
const encrypt = async (key, iv, data) => await window.crypto.subtle.encrypt(aesParams(128, iv), key, data)
const decrypt = async (key, iv, data) => await window.crypto.subtle.decrypt(aesParams(128, iv), key, data)
//init
const init = async() => {
const alice = await derive()
const bob = await derive()
console.log(alice, bob)
qs('#alice').innerText = 'alice public: ' + await keyInt(alice.publicKey)
qs('#bob').innerText = 'bob public: ' + await keyInt(bob.publicKey)
const aes = await deriveAES(bob.publicKey, alice.privateKey)
console.log(aes)
qs('#aes').innerText = 'aes secret: ' + await keyInt(aes)
//listeners
let iv
qs('#encrypt').onclick = async() => {
iv = new Uint8Array(16)
window.crypto.getRandomValues(iv)
const encrypted = await encrypt(aes, iv, new TextEncoder().encode(qs('#text').value))
qs('#text').value = new Uint8Array(encrypted)
}
qs('#decrypt').onclick = async() => {
const encrypted = Uint8Array.from(qs('#text').value.split(','))
const decrypted = await decrypt(aes, iv, encrypted)
qs('#text').value = new TextDecoder().decode(decrypted)
}
}
init()
<div id="alice"></div>
<div id="bob"></div>
<div id="aes"></div>
<div>
<input id="text" />
<br/>
<button id="encrypt">Encrypt</button>
<button id="decrypt">Decrypt</button>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment