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

View File

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

View File

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