Last active
July 1, 2020 10:00
-
-
Save erycson/044f54dfbe1c92ae9638e32dc7105bdd to your computer and use it in GitHub Desktop.
Web Cryptography API + ECDH + AES
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
(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); | |
})(); |
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
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