RSA 관련 프론트엔드 함수 통합

This commit is contained in:
static
2024-12-31 06:34:35 +09:00
parent 214568f2ee
commit f4b9137214
3 changed files with 27 additions and 63 deletions

View File

@@ -1,3 +1,4 @@
export type RSAKeyPurpose = "encryption" | "signature";
export type RSAKeyType = "public" | "private";
export const encodeToBase64 = (data: ArrayBuffer) => {
@@ -8,72 +9,40 @@ export const decodeFromBase64 = (data: string) => {
return Uint8Array.from(atob(data), (c) => c.charCodeAt(0)).buffer;
};
export const generateRSAEncKeyPair = async () => {
const keyPair = await window.crypto.subtle.generateKey(
export const generateRSAKeyPair = async (purpose: RSAKeyPurpose) => {
return await window.crypto.subtle.generateKey(
{
name: "RSA-OAEP",
name: purpose === "encryption" ? "RSA-OAEP" : "RSA-PSS",
modulusLength: 4096,
publicExponent: new Uint8Array([1, 0, 1]),
hash: "SHA-256",
} satisfies RsaHashedKeyGenParams,
true,
["encrypt", "decrypt"],
purpose === "encryption" ? ["encrypt", "decrypt"] : ["sign", "verify"],
);
return keyPair;
};
export const generateRSASigKeyPair = async () => {
const keyPair = await window.crypto.subtle.generateKey(
{
name: "RSA-PSS",
modulusLength: 4096,
publicExponent: new Uint8Array([1, 0, 1]),
hash: "SHA-256",
} satisfies RsaHashedKeyGenParams,
true,
["sign", "verify"],
);
return keyPair;
};
export const makeRSAEncKeyNonextractable = async (key: CryptoKey, type: RSAKeyType) => {
const { format, key: exportedKey } = await exportRSAKey(key, type);
export const makeRSAKeyNonextractable = async (key: CryptoKey) => {
const { format, key: exportedKey } = await exportRSAKey(key);
return await window.crypto.subtle.importKey(
format,
exportedKey,
{
name: "RSA-OAEP",
hash: "SHA-256",
} satisfies RsaHashedImportParams,
key.algorithm,
false,
[type === "public" ? "encrypt" : "decrypt"],
key.usages,
);
};
export const makeRSASigKeyNonextractable = async (key: CryptoKey, type: RSAKeyType) => {
const { format, key: exportedKey } = await exportRSAKey(key, type);
return await window.crypto.subtle.importKey(
format,
exportedKey,
{
name: "RSA-PSS",
hash: "SHA-256",
} satisfies RsaHashedImportParams,
false,
[type === "public" ? "verify" : "sign"],
);
};
const exportRSAKey = async (key: CryptoKey, type: RSAKeyType) => {
const format = type === "public" ? ("spki" as const) : ("pkcs8" as const);
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, type: RSAKeyType) => {
return encodeToBase64((await exportRSAKey(key, type)).key);
export const exportRSAKeyToBase64 = async (key: CryptoKey) => {
return encodeToBase64((await exportRSAKey(key)).key);
};
export const encryptRSAPlaintext = async (plaintext: ArrayBuffer, publicKey: CryptoKey) => {
@@ -122,12 +91,9 @@ export const makeAESKeyNonextractable = async (key: CryptoKey) => {
return await window.crypto.subtle.importKey(
"raw",
await exportAESKey(key),
{
name: "AES-GCM",
length: 256,
} satisfies AesKeyAlgorithm,
key.algorithm,
false,
["encrypt", "decrypt"],
key.usages,
);
};

View File

@@ -20,8 +20,8 @@ export const requestTokenUpgrade = async ({
signKey,
verifyKey,
}: ClientKeys) => {
const encryptKeyBase64 = await exportRSAKeyToBase64(encryptKey, "public");
const verifyKeyBase64 = await exportRSAKeyToBase64(verifyKey, "public");
const encryptKeyBase64 = await exportRSAKeyToBase64(encryptKey);
const verifyKeyBase64 = await exportRSAKeyToBase64(verifyKey);
if (await requestTokenUpgradeInternal(encryptKeyBase64, decryptKey, verifyKeyBase64, signKey)) {
return true;
}

View File

@@ -1,8 +1,6 @@
import {
generateRSAEncKeyPair,
generateRSASigKeyPair,
makeRSAEncKeyNonextractable,
makeRSASigKeyNonextractable,
generateRSAKeyPair,
makeRSAKeyNonextractable,
exportRSAKeyToBase64,
generateAESKey,
makeAESKeyNonextractable,
@@ -11,21 +9,21 @@ import {
import { clientKeyStore, mekStore } from "$lib/stores";
export const generateClientKeys = async () => {
const encKeyPair = await generateRSAEncKeyPair();
const sigKeyPair = await generateRSASigKeyPair();
const encKeyPair = await generateRSAKeyPair("encryption");
const sigKeyPair = await generateRSAKeyPair("signature");
clientKeyStore.set({
encryptKey: encKeyPair.publicKey,
decryptKey: await makeRSAEncKeyNonextractable(encKeyPair.privateKey, "private"),
signKey: await makeRSASigKeyNonextractable(sigKeyPair.privateKey, "private"),
decryptKey: await makeRSAKeyNonextractable(encKeyPair.privateKey),
signKey: await makeRSAKeyNonextractable(sigKeyPair.privateKey),
verifyKey: sigKeyPair.publicKey,
});
return {
encryptKeyBase64: await exportRSAKeyToBase64(encKeyPair.publicKey, "public"),
decryptKeyBase64: await exportRSAKeyToBase64(encKeyPair.privateKey, "private"),
signKeyBase64: await exportRSAKeyToBase64(sigKeyPair.privateKey, "private"),
verifyKeyBase64: await exportRSAKeyToBase64(sigKeyPair.publicKey, "public"),
encryptKeyBase64: await exportRSAKeyToBase64(encKeyPair.publicKey),
decryptKeyBase64: await exportRSAKeyToBase64(encKeyPair.privateKey),
signKeyBase64: await exportRSAKeyToBase64(sigKeyPair.privateKey),
verifyKeyBase64: await exportRSAKeyToBase64(sigKeyPair.publicKey),
};
};