Files
frontend/src/services/vault.service.ts
Ada f6fa19d0b2 feat(vault): add get/create assets API in workflow
TODO: update vault.service.ts. Use MNEMONIC workflow to create real private_key_shard and content_inner_encrypted
2026-02-01 09:19:45 -08:00

82 lines
2.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Vault Service: 为 /assets/create 生成 private_key_shard 与 content_inner_encrypted
*
* 流程(与后端 test_scenario / SentinelVault 一致):
* 1. 用 SSS 生成助记词并分片 → 选一个分片作为 private_key_shard存后端继承时返回
* 2. 用助记词派生 AES 密钥,对明文做 AES-GCM 加密 → content_inner_encryptedhex 字符串)
*
* 使用方式:在任意页面调用 createVaultPayload(plaintext, wordList),得到可直接传给 assetsService.createAsset 的字段。
*/
import {
generateVaultKeys,
serializeShare,
type SSSShare,
type VaultKeyData,
} from '../utils/sss';
import { deriveKey, encryptDataGCM, bytesToHex } from '../utils/vaultCrypto';
export interface CreateVaultPayloadResult {
/** 传给后端的 private_key_shard存一个 SSS 分片的序列化字符串,如云端分片) */
private_key_shard: string;
/** 传给后端的 content_inner_encryptedAES-GCM 密文的 hex */
content_inner_encrypted: string;
/** 本次生成的助记词(用户需妥善保管,恢复时需任意 2 个分片) */
mnemonic: string[];
/** 三个分片device / cloud / heir可与后端返回的 server_shard 组合恢复助记词 */
shares: SSSShare[];
}
export interface CreateAssetPayloadResult {
title: string;
type: string;
private_key_shard: string;
content_inner_encrypted: string;
}
/**
* 生成金库:助记词 + SSS 分片 + 内层加密内容
* @param plaintext 要加密的明文(如遗产说明、账号密码等)
* @param wordList 助记词词表(与 sss 使用的词表一致)
* @param shareIndexForServer 哪个分片存后端0=device, 1=cloud, 2=heir默认 1云端
*/
export async function createVaultPayload(
plaintext: string,
wordList: readonly string[],
shareIndexForServer: 0 | 1 | 2 = 1
): Promise<CreateVaultPayloadResult> {
const { mnemonic, shares }: VaultKeyData = generateVaultKeys(wordList, 12);
const mnemonicPhrase = mnemonic.join(' ');
const key = await deriveKey(mnemonicPhrase);
const encrypted = await encryptDataGCM(key, plaintext);
const content_inner_encrypted = bytesToHex(encrypted);
const shareForServer = shares[shareIndexForServer];
const private_key_shard = serializeShare(shareForServer);
return {
private_key_shard,
content_inner_encrypted,
mnemonic,
shares,
};
}
/**
* 生成可直接用于 POST /assets/create 的请求体(含 title / type
*/
export async function createAssetPayload(
title: string,
plaintext: string,
wordList: readonly string[],
assetType: string = 'note',
shareIndexForServer: 0 | 1 | 2 = 1
): Promise<CreateAssetPayloadResult> {
const vault = await createVaultPayload(plaintext, wordList, shareIndexForServer);
return {
title,
type: assetType,
private_key_shard: vault.private_key_shard,
content_inner_encrypted: vault.content_inner_encrypted,
};
}