@agentunion/fastaun-browser 0.2.14 → 0.2.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,4 @@
1
+ import { type ProtectedHeadersInput } from './e2ee.js';
1
2
  import type { KeyStore } from './keystore/index.js';
2
3
  import { type IdentityRecord, type JsonObject, type Message } from './types.js';
3
4
  export interface LoadedGroupSecret {
@@ -10,6 +11,20 @@ export interface LoadedGroupSecret {
10
11
  epoch_chain_unverified?: boolean;
11
12
  epoch_chain_unverified_reason?: string;
12
13
  }
14
+ /**
15
+ * ECIES 加密(异步,SubtleCrypto)。
16
+ * @param peerPubkeyBytes 65 字节未压缩 P-256 公钥 (0x04 开头)
17
+ * @param plaintext 待加密明文
18
+ * @returns ephemeral_pubkey(65B) || iv(12B) || ciphertext || tag(16B)
19
+ */
20
+ export declare function eciesEncrypt(peerPubkeyBytes: Uint8Array, plaintext: Uint8Array): Promise<Uint8Array>;
21
+ /**
22
+ * ECIES 解密(异步,SubtleCrypto)。
23
+ * @param privateKeyPem PEM 格式 EC 私钥
24
+ * @param ciphertext ephemeral_pubkey(65B) || iv(12B) || encrypted+tag(16B)
25
+ * @returns 解密后的明文
26
+ */
27
+ export declare function eciesDecrypt(privateKeyPem: string, ciphertext: Uint8Array): Promise<Uint8Array>;
13
28
  /**
14
29
  * 计算 Epoch Transcript Chain 哈希(异步,SubtleCrypto SHA-256)。
15
30
  * prev_chain=null 时使用 genesis 前缀,否则将 prev_chain hex 解码为字节。
@@ -41,6 +56,10 @@ export declare function encryptGroupMessage(groupId: string, epoch: number, grou
41
56
  timestamp: number;
42
57
  senderPrivateKeyPem?: string | null;
43
58
  senderCertPem?: string | null;
59
+ protectedHeaders?: ProtectedHeadersInput;
60
+ protected_headers?: ProtectedHeadersInput;
61
+ headers?: ProtectedHeadersInput;
62
+ context?: JsonObject | null;
44
63
  }): Promise<JsonObject>;
45
64
  /**
46
65
  * 解密群组消息(异步)。
@@ -66,6 +85,29 @@ export declare function verifyMembershipManifest(manifest: JsonObject, initiator
66
85
  export declare function computeMembershipCommitment(memberAids: string[], epoch: number, groupId: string, groupSecret: Uint8Array): Promise<string>;
67
86
  /** 验证 Membership Commitment(异步) */
68
87
  export declare function verifyMembershipCommitment(commitment: string, memberAids: string[], epoch: number, groupId: string, myAid: string, groupSecret: Uint8Array): Promise<boolean>;
88
+ /**
89
+ * 计算群组状态哈希(异步,SubtleCrypto SHA-256)。
90
+ *
91
+ * state_hash = SHA-256(
92
+ * group_id | 0x00 |
93
+ * state_version (uint64 big-endian 8 bytes) | 0x00 |
94
+ * key_epoch (uint64 big-endian 8 bytes) | 0x00 |
95
+ * membership_block | 0x00 |
96
+ * policy_block | 0x00 |
97
+ * prev_state_hash (32 bytes, 全零表示创世)
98
+ * )
99
+ */
100
+ export declare function computeStateHash(params: {
101
+ groupId: string;
102
+ stateVersion: number;
103
+ keyEpoch: number;
104
+ members: Array<{
105
+ aid: string;
106
+ role: string;
107
+ }>;
108
+ policy: Record<string, unknown>;
109
+ prevStateHash: string;
110
+ }): Promise<string>;
69
111
  /** 存储 group_secret 到 keystore metadata(异步) */
70
112
  export declare function storeGroupSecret(keystore: KeyStore, aid: string, groupId: string, epoch: number, groupSecret: Uint8Array, commitment: string, memberAids: string[], epochChain?: string, pendingRotationId?: string, epochChainUnverified?: boolean | null, epochChainUnverifiedReason?: string | null): Promise<boolean>;
71
113
  /** 保存指定 epoch key;低于 current 时写入 old epoch,不覆盖 current。 */
@@ -158,6 +200,7 @@ export declare class GroupE2EEManager {
158
200
  /** 指定目标 epoch 号轮换(配合服务端 CAS 使用) */
159
201
  rotateEpochTo(groupId: string, targetEpoch: number, memberAids: string[], opts?: {
160
202
  rotationId?: string;
203
+ prevChainHint?: string | null;
161
204
  }): Promise<JsonObject>;
162
205
  /** 手动存储 group_secret。返回 false 表示 epoch 降级被拒。 */
163
206
  storeSecret(groupId: string, epoch: number, groupSecretBytes: Uint8Array, commitment: string, memberAids: string[], epochChain?: string): Promise<boolean>;
@@ -176,11 +219,19 @@ export declare class GroupE2EEManager {
176
219
  encrypt(groupId: string, payload: JsonObject, opts?: {
177
220
  messageId?: string;
178
221
  timestamp?: number;
222
+ protectedHeaders?: ProtectedHeadersInput;
223
+ protected_headers?: ProtectedHeadersInput;
224
+ headers?: ProtectedHeadersInput;
225
+ context?: JsonObject | null;
179
226
  }): Promise<JsonObject>;
180
227
  /** 使用指定 epoch 加密群消息。 */
181
228
  encryptWithEpoch(groupId: string, epoch: number, payload: JsonObject, opts?: {
182
229
  messageId?: string;
183
230
  timestamp?: number;
231
+ protectedHeaders?: ProtectedHeadersInput;
232
+ protected_headers?: ProtectedHeadersInput;
233
+ headers?: ProtectedHeadersInput;
234
+ context?: JsonObject | null;
184
235
  }): Promise<JsonObject>;
185
236
  /**
186
237
  * 解密单条群消息(异步)。内置防重放 + 发送方验签 + 外层字段校验。
@@ -1 +1 @@
1
- {"version":3,"file":"e2ee-group.d.ts","sourceRoot":"","sources":["../src/e2ee-group.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"e2ee-group.d.ts","sourceRoot":"","sources":["../src/e2ee-group.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,75 @@
1
1
  // ── GroupE2EEManager(群组端到端加密 — 浏览器 SubtleCrypto 实现)──
2
2
  // 所有密码学操作均为异步(SubtleCrypto API 要求)
3
3
  import { E2EEError, E2EEGroupSecretMissingError, } from './errors.js';
4
- import { uint8ToBase64, base64ToUint8, toBufferSource } from './crypto.js';
4
+ import { uint8ToBase64, base64ToUint8, pemToArrayBuffer, toBufferSource } from './crypto.js';
5
5
  import { SUITE, _concatBytes as concatBytes, _certificateSha256Fingerprint as certificateSha256Fingerprint, _ecdsaSignDer as ecdsaSignDer, _ecdsaVerifyDer as ecdsaVerifyDer, _hkdfDerive as hkdfDerive, _aesGcmEncrypt as aesGcmEncrypt, _aesGcmDecrypt as aesGcmDecrypt, _randomNonce as randomNonce, _uuidV4 as uuidV4, _importCertPublicKeyEcdsa as importCertPublicKeyEcdsa, _importPrivateKeyEcdsa as importPrivateKeyEcdsa, } from './e2ee.js';
6
6
  import { isJsonObject, } from './types.js';
7
7
  const _encoder = new TextEncoder();
8
8
  const _decoder = new TextDecoder();
9
+ // ── ECIES (P-256 ECDH + HKDF-SHA256 + AES-256-GCM, SubtleCrypto) ──
10
+ const _ECIES_HKDF_INFO = _encoder.encode('aun-epoch-key-ecies');
11
+ /**
12
+ * ECIES 加密(异步,SubtleCrypto)。
13
+ * @param peerPubkeyBytes 65 字节未压缩 P-256 公钥 (0x04 开头)
14
+ * @param plaintext 待加密明文
15
+ * @returns ephemeral_pubkey(65B) || iv(12B) || ciphertext || tag(16B)
16
+ */
17
+ export async function eciesEncrypt(peerPubkeyBytes, plaintext) {
18
+ // 生成临时 ECDH 密钥对
19
+ const ephemeral = await crypto.subtle.generateKey({ name: 'ECDH', namedCurve: 'P-256' }, true, ['deriveBits']);
20
+ // 导出临时公钥(未压缩 65 字节)
21
+ const ephPubRaw = new Uint8Array(await crypto.subtle.exportKey('raw', ephemeral.publicKey));
22
+ // 导入对方公钥
23
+ const peerKey = await crypto.subtle.importKey('raw', toBufferSource(peerPubkeyBytes), { name: 'ECDH', namedCurve: 'P-256' }, false, []);
24
+ // ECDH 共享密钥
25
+ const sharedBits = await crypto.subtle.deriveBits({ name: 'ECDH', public: peerKey }, ephemeral.privateKey, 256);
26
+ const shared = new Uint8Array(sharedBits);
27
+ // HKDF 派生 32 字节 AES 密钥
28
+ const hkdfKey = await crypto.subtle.importKey('raw', shared, 'HKDF', false, ['deriveBits']);
29
+ const derivedBits = await crypto.subtle.deriveBits({ name: 'HKDF', hash: 'SHA-256', salt: new Uint8Array(0), info: _ECIES_HKDF_INFO }, hkdfKey, 256);
30
+ const aesKeyBytes = new Uint8Array(derivedBits);
31
+ // AES-256-GCM 加密
32
+ const iv = crypto.getRandomValues(new Uint8Array(12));
33
+ const aesKey = await crypto.subtle.importKey('raw', aesKeyBytes, 'AES-GCM', false, ['encrypt']);
34
+ const ctBuf = await crypto.subtle.encrypt({ name: 'AES-GCM', iv: toBufferSource(iv), tagLength: 128 }, aesKey, toBufferSource(plaintext));
35
+ const ctArr = new Uint8Array(ctBuf); // ciphertext + tag(16B)
36
+ // 拼接: ephemeral_pubkey(65) || iv(12) || ciphertext+tag
37
+ const result = new Uint8Array(65 + 12 + ctArr.length);
38
+ result.set(ephPubRaw, 0);
39
+ result.set(iv, 65);
40
+ result.set(ctArr, 77);
41
+ return result;
42
+ }
43
+ /**
44
+ * ECIES 解密(异步,SubtleCrypto)。
45
+ * @param privateKeyPem PEM 格式 EC 私钥
46
+ * @param ciphertext ephemeral_pubkey(65B) || iv(12B) || encrypted+tag(16B)
47
+ * @returns 解密后的明文
48
+ */
49
+ export async function eciesDecrypt(privateKeyPem, ciphertext) {
50
+ if (ciphertext.length < 65 + 12 + 16) {
51
+ throw new E2EEError('ECIES ciphertext too short');
52
+ }
53
+ const ephPubBytes = ciphertext.slice(0, 65);
54
+ const iv = ciphertext.slice(65, 77);
55
+ const encryptedWithTag = ciphertext.slice(77);
56
+ // 导入自己的私钥
57
+ const privKeyDer = pemToArrayBuffer(privateKeyPem);
58
+ const privKey = await crypto.subtle.importKey('pkcs8', privKeyDer, { name: 'ECDH', namedCurve: 'P-256' }, false, ['deriveBits']);
59
+ // 导入临时公钥
60
+ const ephPubKey = await crypto.subtle.importKey('raw', toBufferSource(ephPubBytes), { name: 'ECDH', namedCurve: 'P-256' }, false, []);
61
+ // ECDH 共享密钥
62
+ const sharedBits = await crypto.subtle.deriveBits({ name: 'ECDH', public: ephPubKey }, privKey, 256);
63
+ const shared = new Uint8Array(sharedBits);
64
+ // HKDF 派生 AES 密钥
65
+ const hkdfKey = await crypto.subtle.importKey('raw', shared, 'HKDF', false, ['deriveBits']);
66
+ const derivedBits = await crypto.subtle.deriveBits({ name: 'HKDF', hash: 'SHA-256', salt: new Uint8Array(0), info: _ECIES_HKDF_INFO }, hkdfKey, 256);
67
+ const aesKeyBytes = new Uint8Array(derivedBits);
68
+ // AES-256-GCM 解密(SubtleCrypto 要求 ciphertext+tag 拼接传入)
69
+ const aesKey = await crypto.subtle.importKey('raw', aesKeyBytes, 'AES-GCM', false, ['decrypt']);
70
+ const ptBuf = await crypto.subtle.decrypt({ name: 'AES-GCM', iv: toBufferSource(iv), tagLength: 128 }, aesKey, toBufferSource(encryptedWithTag));
71
+ return new Uint8Array(ptBuf);
72
+ }
9
73
  // ── Epoch Transcript Chain 工具函数 ──────────────────────────
10
74
  /** Genesis 前缀:aun-epoch-chain:genesis(UTF-8 字节) */
11
75
  const _EPOCH_CHAIN_GENESIS_PREFIX = _encoder.encode('aun-epoch-chain:genesis');
@@ -116,6 +180,14 @@ export const AAD_MATCH_FIELDS_GROUP = [
116
180
  'group_id', 'from', 'message_id',
117
181
  'epoch', 'encryption_mode', 'suite',
118
182
  ];
183
+ const AAD_OPTIONAL_FIELDS = [
184
+ 'payload_type', 'protected_headers', 'context_type', 'context_id',
185
+ ];
186
+ const METADATA_AUTH_FIELD = '_auth';
187
+ const METADATA_AUTH_ALG = 'HMAC-SHA256';
188
+ const METADATA_KEY_DOMAIN = _encoder.encode('aun-envelope-metadata-key-v1');
189
+ const PROTECTED_HEADERS_DOMAIN = _encoder.encode('aun-protected-headers-v1');
190
+ const PROTECTED_CONTEXT_DOMAIN = _encoder.encode('aun-protected-context-v1');
119
191
  /** 旧 epoch 默认保留时间(秒) */
120
192
  export const OLD_EPOCH_RETENTION_SECONDS = 7 * 24 * 3600;
121
193
  async function loadKeyStoreGroupEpoch(keystore, aid, groupId, epoch) {
@@ -153,17 +225,170 @@ async function cleanupKeyStoreGroupOldEpochs(keystore, aid, groupId, cutoffMs) {
153
225
  throw new Error(`keystore ${keystore.constructor?.name ?? 'unknown'} missing cleanupGroupOldEpochsState method`);
154
226
  }
155
227
  // ── 群组 AAD 工具 ────────────────────────────────────────────
228
+ function canonicalStringify(value) {
229
+ if (value === null || value === undefined)
230
+ return 'null';
231
+ if (Array.isArray(value)) {
232
+ return `[${value.map(item => canonicalStringify(item)).join(',')}]`;
233
+ }
234
+ if (typeof value === 'object') {
235
+ const record = value;
236
+ const pairs = Object.keys(record)
237
+ .sort()
238
+ .map(key => `${JSON.stringify(key)}:${canonicalStringify(record[key])}`);
239
+ return `{${pairs.join(',')}}`;
240
+ }
241
+ return JSON.stringify(value) ?? 'null';
242
+ }
243
+ function hasOwn(obj, key) {
244
+ return Object.prototype.hasOwnProperty.call(obj, key);
245
+ }
246
+ function normalizeProtectedHeaderKey(key) {
247
+ const value = String(key ?? '').trim().toLowerCase();
248
+ if (!value || !/^[a-z0-9_-]+$/.test(value)) {
249
+ throw new E2EEError('protected header key must match [a-z0-9_-]+');
250
+ }
251
+ if (value === METADATA_AUTH_FIELD) {
252
+ throw new E2EEError('protected header key is reserved');
253
+ }
254
+ return value;
255
+ }
256
+ function normalizeProtectedHeaders(headers) {
257
+ if (headers == null)
258
+ return {};
259
+ const toObject = headers.toObject;
260
+ const raw = typeof toObject === 'function' ? toObject.call(headers) : headers;
261
+ if (typeof raw !== 'object' || Array.isArray(raw)) {
262
+ throw new E2EEError('protected_headers must be an object');
263
+ }
264
+ const result = {};
265
+ for (const [key, value] of Object.entries(raw)) {
266
+ result[normalizeProtectedHeaderKey(key)] = value == null ? '' : String(value);
267
+ }
268
+ return result;
269
+ }
270
+ function metadataBody(metadata) {
271
+ const body = {};
272
+ for (const [key, value] of Object.entries(metadata)) {
273
+ if (key !== METADATA_AUTH_FIELD) {
274
+ body[key] = value;
275
+ }
276
+ }
277
+ return body;
278
+ }
279
+ async function hmacSha256(key, data) {
280
+ const hmacKey = await crypto.subtle.importKey('raw', toBufferSource(key), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
281
+ const sig = await crypto.subtle.sign('HMAC', hmacKey, toBufferSource(data));
282
+ return new Uint8Array(sig);
283
+ }
284
+ async function metadataAuthTag(key, domain, body) {
285
+ const metadataKey = await hmacSha256(key, METADATA_KEY_DOMAIN);
286
+ return hmacSha256(metadataKey, concatBytes(domain, new Uint8Array([0]), _encoder.encode(canonicalStringify(body))));
287
+ }
288
+ async function withMetadataAuth(metadata, key, domain) {
289
+ const body = metadataBody(metadata);
290
+ if (Object.keys(body).length === 0)
291
+ return {};
292
+ const tag = await metadataAuthTag(key, domain, body);
293
+ return {
294
+ ...body,
295
+ [METADATA_AUTH_FIELD]: {
296
+ alg: METADATA_AUTH_ALG,
297
+ tag: uint8ToBase64(tag),
298
+ },
299
+ };
300
+ }
301
+ function timingSafeEqual(a, b) {
302
+ if (a.byteLength !== b.byteLength)
303
+ return false;
304
+ let diff = 0;
305
+ for (let i = 0; i < a.byteLength; i++) {
306
+ diff |= a[i] ^ b[i];
307
+ }
308
+ return diff === 0;
309
+ }
310
+ async function verifyMetadataAuth(metadata, key, domain) {
311
+ if (metadata == null)
312
+ return true;
313
+ if (typeof metadata !== 'object' || Array.isArray(metadata))
314
+ return false;
315
+ const record = metadata;
316
+ const auth = record[METADATA_AUTH_FIELD];
317
+ if (!auth || typeof auth !== 'object' || Array.isArray(auth))
318
+ return false;
319
+ const authObj = auth;
320
+ if (authObj.alg !== METADATA_AUTH_ALG)
321
+ return false;
322
+ if (typeof authObj.tag !== 'string' || !authObj.tag)
323
+ return false;
324
+ const body = metadataBody(record);
325
+ if (Object.keys(body).length === 0)
326
+ return false;
327
+ let actual;
328
+ try {
329
+ actual = base64ToUint8(authObj.tag);
330
+ }
331
+ catch {
332
+ return false;
333
+ }
334
+ const expected = await metadataAuthTag(key, domain, body);
335
+ return timingSafeEqual(actual, expected);
336
+ }
337
+ async function verifyEnvelopeMetadataAuth(payload, messageKey) {
338
+ return await verifyMetadataAuth(payload.protected_headers, messageKey, PROTECTED_HEADERS_DOMAIN)
339
+ && await verifyMetadataAuth(payload.context, messageKey, PROTECTED_CONTEXT_DOMAIN);
340
+ }
341
+ function normalizeContextMetadata(context) {
342
+ if (!context || typeof context !== 'object' || Array.isArray(context))
343
+ return {};
344
+ return metadataBody(context);
345
+ }
346
+ function exposedEnvelopeMetadata(metadata) {
347
+ if (!metadata || typeof metadata !== 'object' || Array.isArray(metadata))
348
+ return undefined;
349
+ const body = metadataBody(metadata);
350
+ return Object.keys(body).length > 0 ? body : undefined;
351
+ }
352
+ async function copyOptionalEnvelopeMetadata(envelope, messageKey, opts) {
353
+ const payloadType = String(opts?.payloadType ?? '').trim();
354
+ const protectedHeaders = normalizeProtectedHeaders(opts?.protectedHeaders);
355
+ if (payloadType) {
356
+ protectedHeaders.payload_type = payloadType;
357
+ }
358
+ if (Object.keys(protectedHeaders).length > 0) {
359
+ envelope.protected_headers = await withMetadataAuth(protectedHeaders, messageKey, PROTECTED_HEADERS_DOMAIN);
360
+ }
361
+ const contextMetadata = normalizeContextMetadata(opts?.context);
362
+ if (Object.keys(contextMetadata).length > 0) {
363
+ envelope.context = await withMetadataAuth(contextMetadata, messageKey, PROTECTED_CONTEXT_DOMAIN);
364
+ }
365
+ }
366
+ function validateDecryptedEnvelopeMetadata(decoded, payload, message) {
367
+ if (payload.protected_headers && typeof payload.protected_headers === 'object' && !Array.isArray(payload.protected_headers)) {
368
+ const headers = metadataBody(payload.protected_headers);
369
+ if (hasOwn(headers, 'payload_type')) {
370
+ if (!decoded || typeof decoded !== 'object' || Array.isArray(decoded))
371
+ return false;
372
+ if (String(decoded.type ?? '') !== String(headers.payload_type ?? '')) {
373
+ return false;
374
+ }
375
+ }
376
+ }
377
+ if (payload.context && typeof payload.context === 'object' && !Array.isArray(payload.context)) {
378
+ const protectedContext = metadataBody(payload.context);
379
+ const outerContext = normalizeContextMetadata(message?.context);
380
+ if (canonicalStringify(outerContext) !== canonicalStringify(protectedContext))
381
+ return false;
382
+ }
383
+ return true;
384
+ }
156
385
  /** 群组 AAD 序列化(排序键、紧凑 JSON) */
157
386
  function aadBytesGroup(aad) {
158
387
  const obj = {};
159
388
  for (const field of AAD_FIELDS_GROUP) {
160
389
  obj[field] = aad[field] ?? null;
161
390
  }
162
- const sorted = {};
163
- for (const key of Object.keys(obj).sort()) {
164
- sorted[key] = obj[key];
165
- }
166
- return _encoder.encode(JSON.stringify(sorted));
391
+ return _encoder.encode(canonicalStringify(obj));
167
392
  }
168
393
  /** 群组 AAD 字段匹配检查 */
169
394
  function aadMatchesGroup(expected, actual) {
@@ -198,19 +423,24 @@ export async function encryptGroupMessage(groupId, epoch, groupSecret, payload,
198
423
  encryption_mode: MODE_EPOCH_GROUP_KEY,
199
424
  suite: SUITE,
200
425
  };
201
- const aadBytes = aadBytesGroup(aad);
202
- const [ciphertext, tag] = await aesGcmEncrypt(msgKey, nonce, plaintext, aadBytes);
203
426
  const envelope = {
204
427
  type: 'e2ee.group_encrypted',
205
428
  version: '1',
206
429
  encryption_mode: MODE_EPOCH_GROUP_KEY,
207
430
  suite: SUITE,
208
431
  epoch,
209
- nonce: uint8ToBase64(nonce),
210
- ciphertext: uint8ToBase64(ciphertext),
211
- tag: uint8ToBase64(tag),
212
- aad,
213
432
  };
433
+ await copyOptionalEnvelopeMetadata(envelope, msgKey, {
434
+ payloadType: payload.type,
435
+ protectedHeaders: opts.protectedHeaders ?? opts.protected_headers ?? opts.headers,
436
+ context: opts.context ?? null,
437
+ });
438
+ const aadBytes = aadBytesGroup(aad);
439
+ const [ciphertext, tag] = await aesGcmEncrypt(msgKey, nonce, plaintext, aadBytes);
440
+ envelope.nonce = uint8ToBase64(nonce);
441
+ envelope.ciphertext = uint8ToBase64(ciphertext);
442
+ envelope.tag = uint8ToBase64(tag);
443
+ envelope.aad = aad;
214
444
  // 发送方签名:对 ciphertext + tag + aad_bytes 签名(不可否认性)
215
445
  if (opts.senderPrivateKeyPem) {
216
446
  const signKey = await importPrivateKeyEcdsa(opts.senderPrivateKeyPem);
@@ -286,20 +516,33 @@ export async function decryptGroupMessage(message, groupSecrets, senderCertPem,
286
516
  const nonce = base64ToUint8(payload.nonce);
287
517
  const ciphertext = base64ToUint8(payload.ciphertext);
288
518
  const tag = base64ToUint8(payload.tag);
519
+ if (!await verifyEnvelopeMetadataAuth(payload, msgKey)) {
520
+ return null;
521
+ }
289
522
  // AAD 校验:直接用 payload 中的 AAD
290
523
  const aadBytes = aad ? aadBytesGroup(aad) : new Uint8Array(0);
291
524
  const plaintext = await aesGcmDecrypt(msgKey, nonce, ciphertext, tag, aadBytes);
292
525
  const decoded = JSON.parse(_decoder.decode(plaintext));
526
+ if (!validateDecryptedEnvelopeMetadata(decoded, payload, message)) {
527
+ return null;
528
+ }
529
+ const e2ee = {
530
+ encryption_mode: MODE_EPOCH_GROUP_KEY,
531
+ suite: SUITE,
532
+ epoch,
533
+ sender_verified: false,
534
+ };
535
+ const protectedHeaders = exposedEnvelopeMetadata(payload.protected_headers);
536
+ if (protectedHeaders)
537
+ e2ee.protected_headers = protectedHeaders;
538
+ const context = exposedEnvelopeMetadata(payload.context);
539
+ if (context)
540
+ e2ee.context = context;
293
541
  const result = {
294
542
  ...message,
295
543
  payload: decoded,
296
544
  encrypted: true,
297
- e2ee: {
298
- encryption_mode: MODE_EPOCH_GROUP_KEY,
299
- suite: SUITE,
300
- epoch,
301
- sender_verified: false,
302
- },
545
+ e2ee,
303
546
  };
304
547
  // 发送方签名验证
305
548
  const senderSigB64 = payload.sender_signature;
@@ -431,6 +674,100 @@ export async function verifyMembershipCommitment(commitment, memberAids, epoch,
431
674
  }
432
675
  return diff === 0;
433
676
  }
677
+ // ── Group State Hash ─────────────────────────────────────────
678
+ /** 将数值编码为 uint64 big-endian 8 字节 */
679
+ function _uint64BE(n) {
680
+ const buf = new Uint8Array(8);
681
+ // JS number 安全整数范围内,高 4 字节用 Math.floor(n / 2^32)
682
+ const hi = Math.floor(n / 0x100000000);
683
+ const lo = n >>> 0;
684
+ buf[0] = (hi >>> 24) & 0xff;
685
+ buf[1] = (hi >>> 16) & 0xff;
686
+ buf[2] = (hi >>> 8) & 0xff;
687
+ buf[3] = hi & 0xff;
688
+ buf[4] = (lo >>> 24) & 0xff;
689
+ buf[5] = (lo >>> 16) & 0xff;
690
+ buf[6] = (lo >>> 8) & 0xff;
691
+ buf[7] = lo & 0xff;
692
+ return buf;
693
+ }
694
+ /** 递归排序 JSON 对象的 key(用于 canonical JSON) */
695
+ function _sortObjectKeys(obj) {
696
+ if (obj === null || obj === undefined || typeof obj !== 'object')
697
+ return obj;
698
+ if (Array.isArray(obj))
699
+ return obj.map(_sortObjectKeys);
700
+ const sorted = {};
701
+ for (const key of Object.keys(obj).sort()) {
702
+ sorted[key] = _sortObjectKeys(obj[key]);
703
+ }
704
+ return sorted;
705
+ }
706
+ /**
707
+ * 计算群组状态哈希(异步,SubtleCrypto SHA-256)。
708
+ *
709
+ * state_hash = SHA-256(
710
+ * group_id | 0x00 |
711
+ * state_version (uint64 big-endian 8 bytes) | 0x00 |
712
+ * key_epoch (uint64 big-endian 8 bytes) | 0x00 |
713
+ * membership_block | 0x00 |
714
+ * policy_block | 0x00 |
715
+ * prev_state_hash (32 bytes, 全零表示创世)
716
+ * )
717
+ */
718
+ export async function computeStateHash(params) {
719
+ const { groupId, stateVersion, keyEpoch, members, policy, prevStateHash } = params;
720
+ // 按 AID 排序,构建 membership_block
721
+ const sorted = [...members].sort((a, b) => a.aid.localeCompare(b.aid));
722
+ const membershipBlock = sorted.map(m => `${m.aid}:${m.role}`).join('|');
723
+ // 按 key 递归排序的 canonical JSON(无空格)
724
+ const policyBlock = Object.keys(policy).length > 0
725
+ ? JSON.stringify(_sortObjectKeys(policy))
726
+ : '';
727
+ // prev_state_hash: 32 字节,空则全零
728
+ const prevBytes = prevStateHash
729
+ ? _hexToBytes(prevStateHash)
730
+ : new Uint8Array(32);
731
+ // state_version / key_epoch → uint64 big-endian
732
+ const svBuf = _uint64BE(stateVersion);
733
+ const keBuf = _uint64BE(keyEpoch);
734
+ const sep = new Uint8Array([0x00]);
735
+ const groupIdBytes = _encoder.encode(groupId);
736
+ const membershipBytes = _encoder.encode(membershipBlock);
737
+ const policyBytes = _encoder.encode(policyBlock);
738
+ // 拼接所有字段
739
+ const totalLen = groupIdBytes.length + 1
740
+ + svBuf.length + 1
741
+ + keBuf.length + 1
742
+ + membershipBytes.length + 1
743
+ + policyBytes.length + 1
744
+ + prevBytes.length;
745
+ const data = new Uint8Array(totalLen);
746
+ let offset = 0;
747
+ data.set(groupIdBytes, offset);
748
+ offset += groupIdBytes.length;
749
+ data.set(sep, offset);
750
+ offset += 1;
751
+ data.set(svBuf, offset);
752
+ offset += svBuf.length;
753
+ data.set(sep, offset);
754
+ offset += 1;
755
+ data.set(keBuf, offset);
756
+ offset += keBuf.length;
757
+ data.set(sep, offset);
758
+ offset += 1;
759
+ data.set(membershipBytes, offset);
760
+ offset += membershipBytes.length;
761
+ data.set(sep, offset);
762
+ offset += 1;
763
+ data.set(policyBytes, offset);
764
+ offset += policyBytes.length;
765
+ data.set(sep, offset);
766
+ offset += 1;
767
+ data.set(prevBytes, offset);
768
+ const digest = await crypto.subtle.digest('SHA-256', data);
769
+ return _bytesToHex(new Uint8Array(digest));
770
+ }
434
771
  // ── Group Secret 生命周期管理 ────────────────────────────────
435
772
  /**
436
773
  * per-group 异步串行化锁,保护 storeGroupSecret 的 load-check-save 原子性。
@@ -694,17 +1031,14 @@ export async function handleKeyRequest(request, keystore, aid, currentMembers, p
694
1031
  const secretData = await loadGroupSecret(keystore, aid, groupId, epoch);
695
1032
  if (!secretData)
696
1033
  return null;
697
- let commitment = secretData.commitment;
1034
+ // P0 历史隔离:若本 epoch 的 member_aids 非空且 requester 不在其中,拒绝响应
1035
+ // 防止已退出成员通过 currentMembers 校验后拿到历史 epoch 密钥
698
1036
  const memberAids = (secretData.member_aids ?? []).map(String).filter(Boolean).sort();
699
- const currentMemberAids = currentMembers.map(String).filter(Boolean).sort();
700
- let responseMemberAids = memberAids.length ? memberAids : currentMemberAids;
701
- let includeEpochChain = true;
702
- if (currentMemberAids.includes(requesterAid) && !responseMemberAids.includes(requesterAid)) {
703
- responseMemberAids = currentMemberAids;
704
- commitment = await computeMembershipCommitment(responseMemberAids, epoch, groupId, secretData.secret);
705
- includeEpochChain = false;
706
- }
707
- else if (!commitment) {
1037
+ if (memberAids.length > 0 && !memberAids.includes(requesterAid))
1038
+ return null;
1039
+ const responseMemberAids = memberAids.length ? memberAids : currentMembers.map(String).filter(Boolean).sort();
1040
+ let commitment = secretData.commitment;
1041
+ if (!commitment) {
708
1042
  commitment = await computeMembershipCommitment(responseMemberAids, epoch, groupId, secretData.secret);
709
1043
  }
710
1044
  const response = {
@@ -719,7 +1053,8 @@ export async function handleKeyRequest(request, keystore, aid, currentMembers, p
719
1053
  responder_aid: aid,
720
1054
  issued_at: Date.now(),
721
1055
  };
722
- if (includeEpochChain && secretData.epoch_chain !== undefined) {
1056
+ // epoch_chain 始终随响应携带(若存在),不再因兼容分支而省略
1057
+ if (secretData.epoch_chain !== undefined) {
723
1058
  response.epoch_chain = secretData.epoch_chain;
724
1059
  }
725
1060
  return privateKeyPem ? await signGroupKeyResponse(response, privateKeyPem) : response;
@@ -768,6 +1103,17 @@ export async function handleKeyResponse(response, keystore, aid, opts) {
768
1103
  const valid = await verifyMembershipCommitment(commitment, memberAids, epoch, groupId, aid, groupSecret);
769
1104
  if (!valid)
770
1105
  return false;
1106
+ const manifest = isJsonObject(payload.manifest) ? payload.manifest : null;
1107
+ if (manifest) {
1108
+ if (manifest.group_id !== groupId || manifest.epoch !== epoch)
1109
+ return false;
1110
+ const manifestMembers = Array.isArray(manifest.member_aids)
1111
+ ? manifest.member_aids.map((item) => String(item ?? '').trim()).filter(Boolean).sort()
1112
+ : [];
1113
+ const payloadMembers = memberAids.map((item) => String(item ?? '').trim()).filter(Boolean).sort();
1114
+ if (manifestMembers.length > 0 && manifestMembers.join('\n') !== payloadMembers.join('\n'))
1115
+ return false;
1116
+ }
771
1117
  const rotationId = typeof payload.rotation_id === 'string' ? payload.rotation_id : '';
772
1118
  const chainAssessment = await assessIncomingEpochChain(keystore, aid, groupId, epoch, commitment, incomingEpochChain, rotationId, String(payload.distributed_by ?? payload.rotator_aid ?? payload.responder_aid ?? ''), 'key_response');
773
1119
  if (!chainAssessment.ok)
@@ -918,7 +1264,10 @@ export class GroupE2EEManager {
918
1264
  const aid = this._currentAid();
919
1265
  const current = await loadGroupSecret(this._keystoreRef, aid, groupId, targetEpoch - 1)
920
1266
  ?? await loadGroupSecret(this._keystoreRef, aid, groupId);
921
- const prevChain = current?.epoch_chain ?? null;
1267
+ let prevChain = current?.epoch_chain ?? null;
1268
+ if (!prevChain && opts?.prevChainHint) {
1269
+ prevChain = opts.prevChainHint;
1270
+ }
922
1271
  const gs = generateGroupSecret();
923
1272
  const commitment = await computeMembershipCommitment(memberAids, targetEpoch, groupId, gs);
924
1273
  const epochChain = await computeEpochChain(prevChain, targetEpoch, commitment, aid);
@@ -971,6 +1320,8 @@ export class GroupE2EEManager {
971
1320
  timestamp: opts?.timestamp ?? Date.now(),
972
1321
  senderPrivateKeyPem: senderPkPem,
973
1322
  senderCertPem,
1323
+ protectedHeaders: opts?.protectedHeaders ?? opts?.protected_headers ?? opts?.headers,
1324
+ context: opts?.context ?? null,
974
1325
  });
975
1326
  }
976
1327
  /** 使用指定 epoch 加密群消息。 */
@@ -992,6 +1343,8 @@ export class GroupE2EEManager {
992
1343
  timestamp: opts?.timestamp ?? Date.now(),
993
1344
  senderPrivateKeyPem: senderPkPem,
994
1345
  senderCertPem,
1346
+ protectedHeaders: opts?.protectedHeaders ?? opts?.protected_headers ?? opts?.headers,
1347
+ context: opts?.context ?? null,
995
1348
  });
996
1349
  }
997
1350
  /**