2023-11-17 11:52:10 +00:00
|
|
|
import { MessageEncryptor, MessageEncryptorPayload, MessageEncryptorVersion } from "..";
|
2023-06-14 14:03:07 +00:00
|
|
|
import { secp256k1 } from "@noble/curves/secp256k1";
|
|
|
|
|
|
|
|
export class Nip4WebCryptoEncryptor implements MessageEncryptor {
|
2023-07-22 18:37:46 +00:00
|
|
|
getSharedSecret(privateKey: string, publicKey: string) {
|
|
|
|
const sharedPoint = secp256k1.getSharedSecret(privateKey, "02" + publicKey);
|
|
|
|
const sharedX = sharedPoint.slice(1, 33);
|
|
|
|
return sharedX;
|
|
|
|
}
|
2023-06-14 14:03:07 +00:00
|
|
|
|
2023-07-22 18:37:46 +00:00
|
|
|
async encryptData(content: string, sharedSecet: Uint8Array) {
|
|
|
|
const key = await this.#importKey(sharedSecet);
|
|
|
|
const iv = window.crypto.getRandomValues(new Uint8Array(16));
|
|
|
|
const data = new TextEncoder().encode(content);
|
|
|
|
const result = await window.crypto.subtle.encrypt(
|
|
|
|
{
|
|
|
|
name: "AES-CBC",
|
|
|
|
iv: iv,
|
|
|
|
},
|
|
|
|
key,
|
2023-07-24 14:30:21 +00:00
|
|
|
data,
|
2023-07-22 18:37:46 +00:00
|
|
|
);
|
2023-08-17 18:54:14 +00:00
|
|
|
return {
|
|
|
|
ciphertext: new Uint8Array(result),
|
|
|
|
nonce: iv,
|
2023-08-17 23:35:48 +00:00
|
|
|
v: MessageEncryptorVersion.Nip4,
|
2023-08-17 18:54:14 +00:00
|
|
|
} as MessageEncryptorPayload;
|
2023-07-22 18:37:46 +00:00
|
|
|
}
|
2023-08-17 23:35:48 +00:00
|
|
|
|
2023-08-17 18:54:14 +00:00
|
|
|
async decryptData(payload: MessageEncryptorPayload, sharedSecet: Uint8Array) {
|
2023-07-22 18:37:46 +00:00
|
|
|
const key = await this.#importKey(sharedSecet);
|
|
|
|
const result = await window.crypto.subtle.decrypt(
|
|
|
|
{
|
|
|
|
name: "AES-CBC",
|
2023-08-17 18:54:14 +00:00
|
|
|
iv: payload.nonce,
|
2023-07-22 18:37:46 +00:00
|
|
|
},
|
|
|
|
key,
|
2023-08-17 23:35:48 +00:00
|
|
|
payload.ciphertext,
|
2023-07-22 18:37:46 +00:00
|
|
|
);
|
|
|
|
return new TextDecoder().decode(result);
|
|
|
|
}
|
2023-06-14 14:03:07 +00:00
|
|
|
|
2023-07-22 18:37:46 +00:00
|
|
|
async #importKey(sharedSecet: Uint8Array) {
|
|
|
|
return await window.crypto.subtle.importKey("raw", sharedSecet, { name: "AES-CBC" }, false, ["encrypt", "decrypt"]);
|
|
|
|
}
|
|
|
|
}
|