mirror of
https://github.com/kmc7468/arkvault.git
synced 2025-12-14 22:08:45 +00:00
103 lines
2.6 KiB
TypeScript
103 lines
2.6 KiB
TypeScript
export type RSAKeyPurpose = "encryption" | "signature";
|
|
export type RSAKeyType = "public" | "private";
|
|
|
|
export const encodeToBase64 = (data: ArrayBuffer) => {
|
|
return btoa(String.fromCharCode(...new Uint8Array(data)));
|
|
};
|
|
|
|
export const decodeFromBase64 = (data: string) => {
|
|
return Uint8Array.from(atob(data), (c) => c.charCodeAt(0)).buffer;
|
|
};
|
|
|
|
export const generateRSAKeyPair = async (purpose: RSAKeyPurpose) => {
|
|
return await window.crypto.subtle.generateKey(
|
|
{
|
|
name: purpose === "encryption" ? "RSA-OAEP" : "RSA-PSS",
|
|
modulusLength: 4096,
|
|
publicExponent: new Uint8Array([1, 0, 1]),
|
|
hash: "SHA-256",
|
|
} satisfies RsaHashedKeyGenParams,
|
|
true,
|
|
purpose === "encryption" ? ["encrypt", "decrypt"] : ["sign", "verify"],
|
|
);
|
|
};
|
|
|
|
export const makeRSAKeyNonextractable = async (key: CryptoKey) => {
|
|
const { format, key: exportedKey } = await exportRSAKey(key);
|
|
return await window.crypto.subtle.importKey(
|
|
format,
|
|
exportedKey,
|
|
key.algorithm,
|
|
false,
|
|
key.usages,
|
|
);
|
|
};
|
|
|
|
export const exportRSAKey = async (key: CryptoKey) => {
|
|
const format = key.type === "public" ? ("spki" as const) : ("pkcs8" as const);
|
|
return {
|
|
format,
|
|
key: await window.crypto.subtle.exportKey(format, key),
|
|
};
|
|
};
|
|
|
|
export const exportRSAKeyToBase64 = async (key: CryptoKey) => {
|
|
return encodeToBase64((await exportRSAKey(key)).key);
|
|
};
|
|
|
|
export const encryptRSAPlaintext = async (plaintext: ArrayBuffer, publicKey: CryptoKey) => {
|
|
return await window.crypto.subtle.encrypt(
|
|
{
|
|
name: "RSA-OAEP",
|
|
} satisfies RsaOaepParams,
|
|
publicKey,
|
|
plaintext,
|
|
);
|
|
};
|
|
|
|
export const decryptRSACiphertext = async (ciphertext: ArrayBuffer, privateKey: CryptoKey) => {
|
|
return await window.crypto.subtle.decrypt(
|
|
{
|
|
name: "RSA-OAEP",
|
|
} satisfies RsaOaepParams,
|
|
privateKey,
|
|
ciphertext,
|
|
);
|
|
};
|
|
|
|
export const signRSAMessage = async (message: ArrayBuffer, privateKey: CryptoKey) => {
|
|
return await window.crypto.subtle.sign(
|
|
{
|
|
name: "RSA-PSS",
|
|
saltLength: 32,
|
|
} satisfies RsaPssParams,
|
|
privateKey,
|
|
message,
|
|
);
|
|
};
|
|
|
|
export const generateAESKey = async () => {
|
|
return await window.crypto.subtle.generateKey(
|
|
{
|
|
name: "AES-GCM",
|
|
length: 256,
|
|
} satisfies AesKeyGenParams,
|
|
true,
|
|
["encrypt", "decrypt"],
|
|
);
|
|
};
|
|
|
|
export const makeAESKeyNonextractable = async (key: CryptoKey) => {
|
|
return await window.crypto.subtle.importKey(
|
|
"raw",
|
|
await exportAESKey(key),
|
|
key.algorithm,
|
|
false,
|
|
key.usages,
|
|
);
|
|
};
|
|
|
|
export const exportAESKey = async (key: CryptoKey) => {
|
|
return await window.crypto.subtle.exportKey("raw", key);
|
|
};
|