Files
WebDrop/packages/core/src/internal.ts
T

43 lines
1.7 KiB
TypeScript

/**
* 仅供测试和调试:把通常不可导出的中间密钥以字节形式导出,用来和测试向量逐字节比对。
* 正常使用请只依赖主入口。这里的函数会让密钥材料暴露在 JS 变量里,不要在产品代码中使用。
*/
import { Labels } from './constants.js';
import { utf8, type Bytes } from './bytes.js';
export { encodeEnvelope, frameAad, frameIv, padPlaintext, parseEnvelope, sealFrame, tierFor, unpadPlaintext } from './frame.js';
export { encodeMeta, decodeFirstFrame, planItem } from './item.js';
export { deriveChannelKeys, deriveItemKey, deriveOwnerToken, sha256 } from './kdf.js';
async function hkdfBytes(ikm: Uint8Array, salt: Uint8Array, label: string): Promise<Bytes> {
const key = await globalThis.crypto.subtle.importKey('raw', ikm as Bytes, 'HKDF', false, ['deriveBits']);
const bits = await globalThis.crypto.subtle.deriveBits(
{ name: 'HKDF', hash: 'SHA-256', salt: salt as Bytes, info: utf8(label) },
key,
256,
);
return new Uint8Array(bits);
}
export interface RawChannelSecrets {
kEnc: Bytes;
tRead: Bytes;
tWrite: Bytes;
kLabel: Bytes;
}
export async function deriveRawChannelSecrets(channelId: Uint8Array, k: Uint8Array): Promise<RawChannelSecrets> {
const kEnc = await hkdfBytes(k, channelId, Labels.enc);
return {
kEnc,
tRead: await hkdfBytes(k, channelId, Labels.read),
tWrite: await hkdfBytes(k, channelId, Labels.write),
kLabel: await hkdfBytes(kEnc, channelId, Labels.label),
};
}
export const deriveRawOwnerToken = (channelId: Uint8Array, a: Uint8Array): Promise<Bytes> => hkdfBytes(a, channelId, Labels.owner);
export const deriveRawItemKey = (kEnc: Uint8Array, itemId: Uint8Array): Promise<Bytes> => hkdfBytes(kEnc, itemId, Labels.item);