mirror of
https://github.com/kmc7468/arkvault.git
synced 2025-12-16 06:58:46 +00:00
클라이언트 승인 대기 페이지 구현
This commit is contained in:
@@ -10,7 +10,7 @@ interface KeyExportState {
|
||||
signKeyBase64: string;
|
||||
verifyKeyBase64: string;
|
||||
|
||||
mekDraft: ArrayBuffer;
|
||||
masterKeyWrapped: ArrayBuffer;
|
||||
}
|
||||
|
||||
const useAutoNull = <T>(value: T | null) => {
|
||||
|
||||
@@ -1,26 +1,36 @@
|
||||
import { Dexie, type EntityTable } from "dexie";
|
||||
|
||||
type RSAKeyUsage = "encrypt" | "decrypt" | "sign" | "verify";
|
||||
type ClientKeyUsage = "encrypt" | "decrypt" | "sign" | "verify";
|
||||
|
||||
interface RSAKey {
|
||||
usage: RSAKeyUsage;
|
||||
interface ClientKey {
|
||||
usage: ClientKeyUsage;
|
||||
key: CryptoKey;
|
||||
}
|
||||
|
||||
type MasterKeyState = "active" | "retired";
|
||||
|
||||
interface MasterKey {
|
||||
version: number;
|
||||
state: MasterKeyState;
|
||||
key: CryptoKey;
|
||||
}
|
||||
|
||||
const keyStore = new Dexie("keyStore") as Dexie & {
|
||||
rsaKey: EntityTable<RSAKey, "usage">;
|
||||
clientKey: EntityTable<ClientKey, "usage">;
|
||||
masterKey: EntityTable<MasterKey, "version">;
|
||||
};
|
||||
|
||||
keyStore.version(1).stores({
|
||||
rsaKey: "usage",
|
||||
clientKey: "usage",
|
||||
masterKey: "version",
|
||||
});
|
||||
|
||||
export const getRSAKey = async (usage: RSAKeyUsage) => {
|
||||
const key = await keyStore.rsaKey.get(usage);
|
||||
export const getClientKey = async (usage: ClientKeyUsage) => {
|
||||
const key = await keyStore.clientKey.get(usage);
|
||||
return key?.key ?? null;
|
||||
};
|
||||
|
||||
export const storeRSAKey = async (key: CryptoKey, usage: RSAKeyUsage) => {
|
||||
export const storeClientKey = async (key: CryptoKey, usage: ClientKeyUsage) => {
|
||||
switch (usage) {
|
||||
case "encrypt":
|
||||
case "verify":
|
||||
@@ -39,5 +49,16 @@ export const storeRSAKey = async (key: CryptoKey, usage: RSAKeyUsage) => {
|
||||
}
|
||||
break;
|
||||
}
|
||||
await keyStore.rsaKey.put({ usage, key });
|
||||
await keyStore.clientKey.put({ usage, key });
|
||||
};
|
||||
|
||||
export const getMasterKeys = async () => {
|
||||
return await keyStore.masterKey.toArray();
|
||||
};
|
||||
|
||||
export const storeMasterKeys = async (keys: MasterKey[]) => {
|
||||
if (keys.some(({ key }) => key.extractable)) {
|
||||
throw new Error("Master keys must be non-extractable");
|
||||
}
|
||||
await keyStore.masterKey.bulkPut(keys);
|
||||
};
|
||||
|
||||
@@ -18,7 +18,7 @@ export const generateRSAKeyPair = async (purpose: RSAKeyPurpose) => {
|
||||
hash: "SHA-256",
|
||||
} satisfies RsaHashedKeyGenParams,
|
||||
true,
|
||||
purpose === "encryption" ? ["encrypt", "decrypt"] : ["sign", "verify"],
|
||||
purpose === "encryption" ? ["encrypt", "decrypt", "wrapKey", "unwrapKey"] : ["sign", "verify"],
|
||||
);
|
||||
};
|
||||
|
||||
@@ -101,6 +101,33 @@ export const exportAESKey = async (key: CryptoKey) => {
|
||||
return await window.crypto.subtle.exportKey("raw", key);
|
||||
};
|
||||
|
||||
export const wrapAESKeyUsingRSA = async (aesKey: CryptoKey, rsaPublicKey: CryptoKey) => {
|
||||
return await window.crypto.subtle.wrapKey("raw", aesKey, rsaPublicKey, {
|
||||
name: "RSA-OAEP",
|
||||
} satisfies RsaOaepParams);
|
||||
};
|
||||
|
||||
export const unwrapAESKeyUsingRSA = async (wrappedKey: BufferSource, rsaPrivateKey: CryptoKey) => {
|
||||
return await window.crypto.subtle.unwrapKey(
|
||||
"raw",
|
||||
wrappedKey,
|
||||
rsaPrivateKey,
|
||||
{
|
||||
name: "RSA-OAEP",
|
||||
} satisfies RsaOaepParams,
|
||||
{
|
||||
name: "AES-GCM",
|
||||
length: 256,
|
||||
} satisfies AesKeyGenParams,
|
||||
true,
|
||||
["encrypt", "decrypt"],
|
||||
);
|
||||
};
|
||||
|
||||
export const digestSHA256 = async (data: BufferSource) => {
|
||||
return await window.crypto.subtle.digest("SHA-256", data);
|
||||
};
|
||||
|
||||
export const signRequest = async <T>(data: T, privateKey: CryptoKey) => {
|
||||
const dataBuffer = new TextEncoder().encode(JSON.stringify(data));
|
||||
const signature = await signRSAMessage(dataBuffer, privateKey);
|
||||
|
||||
@@ -7,5 +7,11 @@ export interface ClientKeys {
|
||||
verifyKey: CryptoKey;
|
||||
}
|
||||
|
||||
export interface MasterKey {
|
||||
state: "active" | "retired" | "dead";
|
||||
masterKey: CryptoKey;
|
||||
}
|
||||
|
||||
export const clientKeyStore = writable<ClientKeys | null>(null);
|
||||
export const mekStore = writable<Map<number, CryptoKey>>(new Map());
|
||||
|
||||
export const masterKeyStore = writable<Map<number, MasterKey> | null>(null);
|
||||
|
||||
Reference in New Issue
Block a user