프론트엔드 암호 모듈 리팩토링

This commit is contained in:
static
2025-01-03 12:21:53 +09:00
parent afe672228a
commit aad5617d25
15 changed files with 336 additions and 298 deletions

View File

@@ -9,7 +9,9 @@
let { data } = $props();
const fingerprint = $derived(
$clientKeyStore ? generateEncryptKeyFingerprint($clientKeyStore.encryptKey) : undefined,
$clientKeyStore
? generateEncryptKeyFingerprint($clientKeyStore.encryptKey, $clientKeyStore.verifyKey)
: undefined,
);
$effect(() => {

View File

@@ -1,10 +1,14 @@
import { exportRSAKey, digestSHA256 } from "$lib/modules/crypto";
import { concatenateBuffers, exportRSAKey, digestMessage } from "$lib/modules/crypto";
export { requestMasterKeyDownload } from "$lib/services/key";
export const generateEncryptKeyFingerprint = async (encryptKey: CryptoKey) => {
const { key } = await exportRSAKey(encryptKey);
const digest = await digestSHA256(key);
export const generateEncryptKeyFingerprint = async (
encryptKey: CryptoKey,
verifyKey: CryptoKey,
) => {
const { key: encryptKeyBuffer } = await exportRSAKey(encryptKey);
const { key: verifyKeyBuffer } = await exportRSAKey(verifyKey);
const digest = await digestMessage(concatenateBuffers(encryptKeyBuffer, verifyKeyBuffer));
return Array.from(new Uint8Array(digest))
.map((byte) => byte.toString(16).padStart(2, "0"))
.join("")

View File

@@ -1,6 +1,6 @@
import { callSignedPostApi } from "$lib/hooks";
import { storeClientKey } from "$lib/indexedDB";
import { encodeToBase64, signMasterKeyWrapped } from "$lib/modules/crypto";
import { signMasterKeyWrapped } from "$lib/modules/crypto";
import type { InitialMasterKeyRegisterRequest } from "$lib/server/schemas";
import type { ClientKeys } from "$lib/stores";
@@ -43,13 +43,13 @@ export const storeClientKeys = async (clientKeys: ClientKeys) => {
};
export const requestInitialMasterKeyRegistration = async (
masterKeyWrapped: ArrayBuffer,
masterKeyWrapped: string,
signKey: CryptoKey,
) => {
const res = await callSignedPostApi<InitialMasterKeyRegisterRequest>(
"/api/mek/register/initial",
{
mek: encodeToBase64(masterKeyWrapped),
mek: masterKeyWrapped,
mekSig: await signMasterKeyWrapped(1, masterKeyWrapped, signKey),
},
signKey,

View File

@@ -1,35 +1,36 @@
import {
generateRSAKeyPair,
makeRSAKeyNonextractable,
generateEncryptionKeyPair,
generateSigningKeyPair,
exportRSAKeyToBase64,
generateAESMasterKey,
wrapAESMasterKey,
makeRSAKeyNonextractable,
generateMasterKey,
wrapMasterKey,
} from "$lib/modules/crypto";
import { clientKeyStore } from "$lib/stores";
export const generateClientKeys = async () => {
const encKeyPair = await generateRSAKeyPair("encryption");
const sigKeyPair = await generateRSAKeyPair("signature");
const { encryptKey, decryptKey } = await generateEncryptionKeyPair();
const { signKey, verifyKey } = await generateSigningKeyPair();
clientKeyStore.set({
encryptKey: encKeyPair.publicKey,
decryptKey: await makeRSAKeyNonextractable(encKeyPair.privateKey),
signKey: await makeRSAKeyNonextractable(sigKeyPair.privateKey),
verifyKey: sigKeyPair.publicKey,
encryptKey,
decryptKey: await makeRSAKeyNonextractable(decryptKey),
signKey: await makeRSAKeyNonextractable(signKey),
verifyKey,
});
return {
encryptKey: encKeyPair.publicKey,
encryptKeyBase64: await exportRSAKeyToBase64(encKeyPair.publicKey),
decryptKeyBase64: await exportRSAKeyToBase64(encKeyPair.privateKey),
signKeyBase64: await exportRSAKeyToBase64(sigKeyPair.privateKey),
verifyKeyBase64: await exportRSAKeyToBase64(sigKeyPair.publicKey),
encryptKey,
encryptKeyBase64: await exportRSAKeyToBase64(encryptKey),
decryptKeyBase64: await exportRSAKeyToBase64(decryptKey),
signKeyBase64: await exportRSAKeyToBase64(signKey),
verifyKeyBase64: await exportRSAKeyToBase64(verifyKey),
};
};
export const generateInitialMasterKey = async (encryptKey: CryptoKey) => {
const masterKey = await generateAESMasterKey();
const { masterKey } = await generateMasterKey();
return {
masterKeyWrapped: await wrapAESMasterKey(masterKey, encryptKey),
masterKeyWrapped: await wrapMasterKey(masterKey, encryptKey),
};
};

View File

@@ -2,11 +2,11 @@ import { callSignedPostApi } from "$lib/hooks";
import {
encodeToBase64,
decodeFromBase64,
generateAESDataKey,
encryptAESPlaintext,
decryptAESCiphertext,
wrapAESDataKey,
unwrapAESDataKey,
generateDataKey,
wrapDataKey,
unwrapDataKey,
encryptData,
decryptData,
} from "$lib/modules/crypto";
import type { DirectroyInfoResponse, DirectoryCreateRequest } from "$lib/server/schemas";
import type { MasterKey } from "$lib/stores";
@@ -15,14 +15,10 @@ export const decryptDirectroyMetadata = async (
metadata: NonNullable<DirectroyInfoResponse["metadata"]>,
masterKey: CryptoKey,
) => {
const dataDecryptKey = await unwrapAESDataKey(decodeFromBase64(metadata.dek), masterKey);
const { dataKey } = await unwrapDataKey(metadata.dek, masterKey);
return {
name: new TextDecoder().decode(
await decryptAESCiphertext(
decodeFromBase64(metadata.name),
decodeFromBase64(metadata.nameIv),
dataDecryptKey,
),
await decryptData(decodeFromBase64(metadata.name), metadata.nameIv, dataKey),
),
};
};
@@ -33,16 +29,16 @@ export const requestDirectroyCreation = async (
masterKey: MasterKey,
signKey: CryptoKey,
) => {
const dataKey = await generateAESDataKey();
const nameEncrypted = await encryptAESPlaintext(new TextEncoder().encode(name), dataKey);
const { dataKey } = await generateDataKey();
const nameEncrypted = await encryptData(new TextEncoder().encode(name), dataKey);
return await callSignedPostApi<DirectoryCreateRequest>(
"/api/directory/create",
{
parentId,
mekVersion: masterKey.version,
dek: encodeToBase64(await wrapAESDataKey(dataKey, masterKey.key)),
dek: await wrapDataKey(dataKey, masterKey.key),
name: encodeToBase64(nameEncrypted.ciphertext),
nameIv: encodeToBase64(nameEncrypted.iv.buffer),
nameIv: nameEncrypted.iv,
},
signKey,
);