mirror of
https://github.com/Nathanwoodburn/hnschat-web.git
synced 2025-12-18 14:23:02 +11:00
v2
This commit is contained in:
124
assets/js/e2ee.js
Executable file
124
assets/js/e2ee.js
Executable file
@@ -0,0 +1,124 @@
|
||||
export class e2ee {
|
||||
async generateKeys() {
|
||||
const keyPair = await window.crypto.subtle.generateKey(
|
||||
{
|
||||
name: "ECDH",
|
||||
namedCurve: "P-256",
|
||||
},
|
||||
true,
|
||||
["deriveKey", "deriveBits"]
|
||||
);
|
||||
|
||||
const publicKeyJwk = await window.crypto.subtle.exportKey(
|
||||
"jwk",
|
||||
keyPair.publicKey
|
||||
);
|
||||
|
||||
const privateKeyJwk = await window.crypto.subtle.exportKey(
|
||||
"jwk",
|
||||
keyPair.privateKey
|
||||
);
|
||||
|
||||
return { publicKeyJwk, privateKeyJwk };
|
||||
}
|
||||
|
||||
async importKey(x, y, d) {
|
||||
const privateKey = await window.crypto.subtle.importKey(
|
||||
"jwk",
|
||||
{
|
||||
kty: "EC",
|
||||
crv: "P-256",
|
||||
x: x,
|
||||
y: y,
|
||||
d: d,
|
||||
ext: true,
|
||||
},
|
||||
{
|
||||
name: "ECDH",
|
||||
namedCurve: "P-256",
|
||||
},
|
||||
true,
|
||||
["deriveKey", "deriveBits"]
|
||||
);
|
||||
|
||||
const privateKeyJwk = await window.crypto.subtle.exportKey(
|
||||
"jwk",
|
||||
privateKey
|
||||
);
|
||||
|
||||
return privateKeyJwk;
|
||||
}
|
||||
|
||||
async deriveKey(publicKeyJwk, privateKeyJwk) {
|
||||
const publicKey = await window.crypto.subtle.importKey(
|
||||
"jwk",
|
||||
publicKeyJwk,
|
||||
{
|
||||
name: "ECDH",
|
||||
namedCurve: "P-256",
|
||||
},
|
||||
true,
|
||||
[]
|
||||
);
|
||||
|
||||
const privateKey = await window.crypto.subtle.importKey(
|
||||
"jwk",
|
||||
privateKeyJwk,
|
||||
{
|
||||
name: "ECDH",
|
||||
namedCurve: "P-256",
|
||||
},
|
||||
true,
|
||||
["deriveKey", "deriveBits"]
|
||||
);
|
||||
|
||||
return await window.crypto.subtle.deriveKey(
|
||||
{ name: "ECDH", public: publicKey },
|
||||
privateKey,
|
||||
{ name: "AES-GCM", length: 256 },
|
||||
true,
|
||||
["encrypt", "decrypt"]
|
||||
);
|
||||
};
|
||||
|
||||
async encryptMessage(text, derivedKey, conversation) {
|
||||
const encodedText = new TextEncoder().encode(text);
|
||||
|
||||
const encryptedData = await window.crypto.subtle.encrypt(
|
||||
{ name: "AES-GCM", iv: new TextEncoder().encode(conversation) },
|
||||
derivedKey,
|
||||
encodedText
|
||||
);
|
||||
|
||||
const uintArray = new Uint8Array(encryptedData);
|
||||
const string = String.fromCharCode.apply(null, uintArray);
|
||||
const base64Data = btoa(string);
|
||||
|
||||
return base64Data;
|
||||
};
|
||||
|
||||
async decryptMessage(text, derivedKey, conversation) {
|
||||
try {
|
||||
const initializationVector = new Uint8Array(new TextEncoder().encode(conversation)).buffer;
|
||||
|
||||
const string = atob(text);
|
||||
const uintArray = new Uint8Array(
|
||||
[...string].map((char) => char.charCodeAt(0))
|
||||
);
|
||||
const algorithm = {
|
||||
name: "AES-GCM",
|
||||
iv: initializationVector,
|
||||
};
|
||||
const decryptedData = await window.crypto.subtle.decrypt(
|
||||
algorithm,
|
||||
derivedKey,
|
||||
uintArray
|
||||
);
|
||||
|
||||
return new TextDecoder().decode(decryptedData);
|
||||
}
|
||||
catch {
|
||||
return text;
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user