snort/packages/system/src/impl/nip4.ts

47 lines
1.4 KiB
TypeScript
Raw Normal View History

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"]);
}
}