Skip to content

Instantly share code, notes, and snippets.

@erycson
Last active July 1, 2020 10:00
Show Gist options
  • Save erycson/044f54dfbe1c92ae9638e32dc7105bdd to your computer and use it in GitHub Desktop.
Save erycson/044f54dfbe1c92ae9638e32dc7105bdd to your computer and use it in GitHub Desktop.
Web Cryptography API + ECDH + AES
(async () => {
// Generate Keys
const pro1 = new Protector();
await pro1.generateKey();
const pub1 = pro1.getPublicKey();
const pro2 = new Protector();
await pro2.generateKey();
const pub2 = pro2.getPublicKey();
// Exchange Keys
await pro1.setRemotePublicKey(pub2);
await pro2.setRemotePublicKey(pub1);
// Let`s Encrypt
const crypted = await pro1.encrypt('Hello World');
const descrypted = await pro2.decrypt(crypted);
})();
class Protector {
ab2str(buffer) {
return new TextDecoder().decode(buffer);
}
str2ab(text) {
return new TextEncoder().encode(text);
}
generateIv() {
return crypto.getRandomValues(new Uint8Array(16));
}
/**
* @see https://github.com/mdn/dom-examples/blob/master/web-crypto/derive-bits/ecdh.js
*/
async generateKey() {
this.key = await window.crypto.subtle.generateKey(
{ name: 'ECDH', namedCurve: 'P-256' },
false,
['deriveBits']
);
}
async encrypt(plaintext) {
const counter = this.generateIv();
const buffer = await crypto.subtle.decrypt({
name: 'aes-ctr',
counter: counter,
length: 128
}, this.importedKey, this.str2ab(plaintext));
return { buffer, counter };
}
async decrypt(data) {
const buffer = await crypto.subtle.decrypt({
name: 'aes-ctr',
counter: data.counter,
length: 128
}, this.importedKey, data.buffer);
return this.ab2str(buffer);
}
getPublicKey() {
return {publicKey: this.key.publicKey};
}
async setRemotePublicKey(key) {
this.clientKey = key;
this.sharedSecret = await window.crypto.subtle.deriveBits(
{ name: 'ECDH', namedCurve: 'P-256', public: this.clientKey.publicKey },
this.key.privateKey,
256
);
this.importedKey = await crypto.subtle.importKey(
'raw',
this.sharedSecret,
'aes-ctr',
false,
['encrypt', 'decrypt']
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment