mirror of
https://github.com/kmc7468/arkvault.git
synced 2026-02-04 08:06:56 +00:00
HMAC 계산을 Web Worker에서 처리하도록 변경
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { hmac } from "@noble/hashes/hmac.js";
|
import HmacWorker from "$workers/hmac?worker";
|
||||||
import { sha256 } from "@noble/hashes/sha2.js";
|
import type { ComputeMessage, ResultMessage } from "$workers/hmac";
|
||||||
|
|
||||||
export const digestMessage = async (message: BufferSource) => {
|
export const digestMessage = async (message: BufferSource) => {
|
||||||
return await crypto.subtle.digest("SHA-256", message);
|
return await crypto.subtle.digest("SHA-256", message);
|
||||||
@@ -18,10 +18,24 @@ export const generateHmacSecret = async () => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createHmacStream = async (hmacSecret: CryptoKey) => {
|
export const signMessageHmac = async (message: Blob, hmacSecret: CryptoKey) => {
|
||||||
const h = hmac.create(sha256, new Uint8Array(await crypto.subtle.exportKey("raw", hmacSecret)));
|
const worker = new HmacWorker();
|
||||||
return {
|
const stream = message.stream();
|
||||||
update: (data: Uint8Array) => h.update(data),
|
const hmacSecretRaw = new Uint8Array(await crypto.subtle.exportKey("raw", hmacSecret));
|
||||||
digest: () => h.digest(),
|
|
||||||
};
|
return new Promise<Uint8Array>((resolve, reject) => {
|
||||||
|
worker.onmessage = (event: MessageEvent<ResultMessage>) => {
|
||||||
|
resolve(event.data.result);
|
||||||
|
worker.terminate();
|
||||||
|
};
|
||||||
|
|
||||||
|
worker.onerror = ({ error }) => {
|
||||||
|
reject(error);
|
||||||
|
worker.terminate();
|
||||||
|
};
|
||||||
|
|
||||||
|
worker.postMessage({ stream, key: hmacSecretRaw } satisfies ComputeMessage, {
|
||||||
|
transfer: [stream, hmacSecretRaw.buffer],
|
||||||
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,13 +1,8 @@
|
|||||||
import ExifReader from "exifreader";
|
import ExifReader from "exifreader";
|
||||||
import { limitFunction } from "p-limit";
|
import { limitFunction } from "p-limit";
|
||||||
import { CHUNK_SIZE } from "$lib/constants";
|
import { CHUNK_SIZE } from "$lib/constants";
|
||||||
import {
|
import { encodeToBase64, generateDataKey, wrapDataKey, encryptString } from "$lib/modules/crypto";
|
||||||
encodeToBase64,
|
import { signMessageHmac } from "$lib/modules/crypto";
|
||||||
generateDataKey,
|
|
||||||
wrapDataKey,
|
|
||||||
encryptString,
|
|
||||||
createHmacStream,
|
|
||||||
} from "$lib/modules/crypto";
|
|
||||||
import { Scheduler } from "$lib/modules/scheduler";
|
import { Scheduler } from "$lib/modules/scheduler";
|
||||||
import { generateThumbnail } from "$lib/modules/thumbnail";
|
import { generateThumbnail } from "$lib/modules/thumbnail";
|
||||||
import { uploadBlob } from "$lib/modules/upload";
|
import { uploadBlob } from "$lib/modules/upload";
|
||||||
@@ -56,16 +51,8 @@ export const clearUploadedFiles = () => {
|
|||||||
|
|
||||||
const requestDuplicateFileScan = limitFunction(
|
const requestDuplicateFileScan = limitFunction(
|
||||||
async (file: File, hmacSecret: HmacSecret, onDuplicate: () => Promise<boolean>) => {
|
async (file: File, hmacSecret: HmacSecret, onDuplicate: () => Promise<boolean>) => {
|
||||||
const hmacStream = await createHmacStream(hmacSecret.secret);
|
const hmacResult = await signMessageHmac(file, hmacSecret.secret);
|
||||||
const reader = file.stream().getReader();
|
const fileSigned = encodeToBase64(hmacResult);
|
||||||
|
|
||||||
while (true) {
|
|
||||||
const { done, value } = await reader.read();
|
|
||||||
if (done) break;
|
|
||||||
hmacStream.update(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
const fileSigned = encodeToBase64(hmacStream.digest());
|
|
||||||
const files = await trpc().file.listByHash.query({
|
const files = await trpc().file.listByHash.query({
|
||||||
hskVersion: hmacSecret.version,
|
hskVersion: hmacSecret.version,
|
||||||
contentHmac: fileSigned,
|
contentHmac: fileSigned,
|
||||||
|
|||||||
25
src/workers/hmac.ts
Normal file
25
src/workers/hmac.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { hmac } from "@noble/hashes/hmac.js";
|
||||||
|
import { sha256 } from "@noble/hashes/sha2.js";
|
||||||
|
|
||||||
|
export interface ComputeMessage {
|
||||||
|
stream: ReadableStream;
|
||||||
|
key: Uint8Array;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ResultMessage {
|
||||||
|
result: Uint8Array;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.onmessage = async (event: MessageEvent<ComputeMessage>) => {
|
||||||
|
const h = hmac.create(sha256, event.data.key);
|
||||||
|
const reader = event.data.stream.getReader();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
const { done, value } = await reader.read();
|
||||||
|
if (done) break;
|
||||||
|
h.update(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = h.digest();
|
||||||
|
self.postMessage({ result } satisfies ResultMessage, { transfer: [result.buffer] });
|
||||||
|
};
|
||||||
@@ -8,6 +8,7 @@ const config = {
|
|||||||
adapter: adapter(),
|
adapter: adapter(),
|
||||||
alias: {
|
alias: {
|
||||||
$trpc: "./src/trpc",
|
$trpc: "./src/trpc",
|
||||||
|
$workers: "./src/workers",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user