@h-ai/crypto 0.1.0-alpha8 → 1.0.0-beta.1

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.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../messages/en-US.json","../messages/zh-CN.json","../src/crypto-i18n.ts","../src/crypto-types.ts","../src/crypto-password.ts","../src/crypto-utils.ts","../src/crypto-sm2.ts","../src/crypto-sm3.ts","../src/crypto-sm4.ts","../src/crypto-main.ts"],"names":["core","ok","err","smCrypto","sm3","crypto"],"mappings":"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","file":"index.js","sourcesContent":["{\n \"$schema\": \"https://inlang.com/schema/inlang-message-format\",\n \"crypto_notInitialized\": \"Crypto module not initialized, call crypto.init() first\",\n \"crypto_initFailed\": \"Crypto module initialization failed: {error}\",\n \"crypto_sm2PublicKeyInvalid\": \"Invalid SM2 public key format\",\n \"crypto_sm2PrivateKeyInvalid\": \"Invalid SM2 private key format\",\n \"crypto_sm2EncryptEmpty\": \"SM2 encryption returned empty result\",\n \"crypto_sm2DecryptFailed\": \"SM2 decryption failed or returned invalid result\",\n \"crypto_sm2SignEmpty\": \"SM2 signature returned empty result\",\n \"crypto_sm2KeyPairGenerateFailed\": \"SM2 key pair generation failed: {error}\",\n \"crypto_sm2EncryptFailed\": \"SM2 encryption failed: {error}\",\n \"crypto_sm2DecryptFailedWithError\": \"SM2 decryption failed: {error}\",\n \"crypto_sm2SignFailed\": \"SM2 signing failed: {error}\",\n \"crypto_sm2VerifyFailed\": \"SM2 verification failed: {error}\",\n \"crypto_sm3HashEmpty\": \"SM3 hash returned empty result\",\n \"crypto_sm3HashFailed\": \"SM3 hash calculation failed: {error}\",\n \"crypto_sm3HmacFailed\": \"HMAC-SM3 calculation failed: {error}\",\n \"crypto_sm3VerifyFailed\": \"SM3 hash verification failed: {error}\",\n \"crypto_sm4KeyInvalid\": \"SM4 key must be 16 bytes (32 hex characters)\",\n \"crypto_sm4CbcNeedIv\": \"CBC mode requires IV\",\n \"crypto_sm4IvInvalid\": \"SM4 IV must be 16 bytes (32 hex characters)\",\n \"crypto_sm4EncryptEmpty\": \"SM4 encryption returned empty result\",\n \"crypto_sm4DecryptFailed\": \"SM4 decryption failed\",\n \"crypto_sm4EncryptFailed\": \"SM4 encryption failed: {error}\",\n \"crypto_sm4DecryptFailedWithError\": \"SM4 decryption failed: {error}\",\n \"crypto_passwordEmpty\": \"Password cannot be empty\",\n \"crypto_passwordHashEmpty\": \"Password and hash cannot be empty\",\n \"crypto_passwordHashFailed\": \"Password hashing failed\",\n \"crypto_hashFormatInvalid\": \"Invalid hash format\",\n \"crypto_passwordVerifyFailed\": \"Password verification failed\"\n}\n","{\n \"$schema\": \"https://inlang.com/schema/inlang-message-format\",\n \"crypto_notInitialized\": \"加密模块尚未初始化,请先调用 crypto.init()\",\n \"crypto_initFailed\": \"加密模块初始化失败:{error}\",\n \"crypto_sm2PublicKeyInvalid\": \"无效的 SM2 公钥格式\",\n \"crypto_sm2PrivateKeyInvalid\": \"无效的 SM2 私钥格式\",\n \"crypto_sm2EncryptEmpty\": \"SM2 加密返回空结果\",\n \"crypto_sm2DecryptFailed\": \"SM2 解密失败或返回无效结果\",\n \"crypto_sm2SignEmpty\": \"SM2 签名返回空结果\",\n \"crypto_sm2KeyPairGenerateFailed\": \"SM2 密钥对生成失败: {error}\",\n \"crypto_sm2EncryptFailed\": \"SM2 加密失败: {error}\",\n \"crypto_sm2DecryptFailedWithError\": \"SM2 解密失败: {error}\",\n \"crypto_sm2SignFailed\": \"SM2 签名失败: {error}\",\n \"crypto_sm2VerifyFailed\": \"SM2 验签失败: {error}\",\n \"crypto_sm3HashEmpty\": \"SM3 哈希返回空结果\",\n \"crypto_sm3HashFailed\": \"SM3 哈希计算失败: {error}\",\n \"crypto_sm3HmacFailed\": \"HMAC-SM3 计算失败: {error}\",\n \"crypto_sm3VerifyFailed\": \"SM3 哈希验证失败: {error}\",\n \"crypto_sm4KeyInvalid\": \"SM4 密钥必须为 16 字节(32 个十六进制字符)\",\n \"crypto_sm4CbcNeedIv\": \"CBC 模式必须提供 IV\",\n \"crypto_sm4IvInvalid\": \"SM4 IV 必须为 16 字节(32 个十六进制字符)\",\n \"crypto_sm4EncryptEmpty\": \"SM4 加密返回空结果\",\n \"crypto_sm4DecryptFailed\": \"SM4 解密失败\",\n \"crypto_sm4EncryptFailed\": \"SM4 加密失败: {error}\",\n \"crypto_sm4DecryptFailedWithError\": \"SM4 解密失败: {error}\",\n \"crypto_passwordEmpty\": \"密码不能为空\",\n \"crypto_passwordHashEmpty\": \"密码和哈希值不能为空\",\n \"crypto_passwordHashFailed\": \"密码哈希失败\",\n \"crypto_hashFormatInvalid\": \"无效的哈希格式\",\n \"crypto_passwordVerifyFailed\": \"密码验证失败\"\n}\n","/**\n * @h-ai/crypto — i18n\n *\n * 本文件提供加密模块的 i18n 文案访问入口。\n * @module crypto-i18n\n */\n\nimport { core } from '@h-ai/core'\nimport messagesEnUS from '../messages/en-US.json'\nimport messagesZhCN from '../messages/zh-CN.json'\n\n/** 加密模块 i18n 消息键类型(自动从 zh-CN 消息文件推断) */\ntype CryptoMessageKey = keyof typeof messagesZhCN\n\n/**\n * 加密模块 i18n 消息获取器\n *\n * 根据当前全局 locale 返回对应语言的消息文本,支持参数插值。\n *\n * @example\n * ```ts\n * cryptoM('crypto_sm2PublicKeyInvalid')\n * cryptoM('crypto_initFailed', { params: { error: 'bad config' } })\n * ```\n */\nexport const cryptoM = core.i18n.createMessageGetter<CryptoMessageKey>({\n 'zh-CN': messagesZhCN,\n 'en-US': messagesEnUS,\n})\n","/**\n * @h-ai/crypto — 公共类型\n *\n * 定义加密模块的对外接口类型。\n * @module crypto-types\n */\n\nimport type { ErrorInfo, HaiResult } from '@h-ai/core'\nimport { core } from '@h-ai/core'\n\nconst CryptoErrorInfo = {\n INVALID_INPUT: '002:400',\n INVALID_KEY: '003:400',\n NOT_INITIALIZED: '010:500',\n INIT_FAILED: '011:500',\n KEY_GENERATION_FAILED: '020:500',\n ENCRYPTION_FAILED: '021:500',\n DECRYPTION_FAILED: '022:500',\n SIGN_FAILED: '023:500',\n VERIFY_FAILED: '024:500',\n HASH_FAILED: '040:500',\n HMAC_FAILED: '041:500',\n INVALID_IV: '060:400',\n} as const satisfies ErrorInfo\n\nexport const HaiCryptoError = core.error.buildHaiErrorsDef('crypto', CryptoErrorInfo)\n\n// ─── 非对称加密类型 ───\n\n/** 密文模式:0=C1C2C3(旧版),1=C1C3C2(国标) */\nexport type CipherMode = 0 | 1\n\n/** 非对称密钥对 */\nexport interface KeyPair {\n /** 公钥(十六进制字符串,包含 04 前缀为非压缩格式) */\n publicKey: string\n /** 私钥(十六进制字符串,64 字符) */\n privateKey: string\n}\n\n/** 非对称加密选项 */\nexport interface AsymmetricEncryptOptions {\n /** 密文模式:0=C1C2C3(旧版),1=C1C3C2(国标,默认) */\n cipherMode?: CipherMode\n /** 输出格式 */\n outputFormat?: 'hex' | 'base64'\n}\n\n/** 签名选项 */\nexport interface SignOptions {\n /** 是否对数据进行哈希(默认 true) */\n hash?: boolean\n /** 用户 ID(默认 \"1234567812345678\") */\n userId?: string\n}\n\n// ─── 哈希类型 ───\n\n/** 哈希选项 */\nexport interface HashOptions {\n /** 输入编码 */\n inputEncoding?: 'utf8' | 'hex'\n}\n\n// ─── 对称加密类型 ───\n\n/** 对称加密模式 */\nexport type SymmetricMode = 'ecb' | 'cbc'\n\n/** 对称加密选项 */\nexport interface SymmetricOptions {\n /** 加密模式 */\n mode?: SymmetricMode\n /** IV 向量(CBC 模式必需,32 个十六进制字符) */\n iv?: string\n /** 输入编码 */\n inputEncoding?: 'utf8' | 'hex'\n /** 输出格式 */\n outputFormat?: 'hex' | 'base64'\n}\n\n/** 带 IV 加密结果 */\nexport interface EncryptWithIVResult {\n /** 密文 */\n ciphertext: string\n /** IV 向量 */\n iv: string\n}\n\n// ─── 密码类型 ───\n\n/** 密码哈希配置 */\nexport interface PasswordConfig {\n /** 盐值长度(默认 16) */\n saltLength?: number\n /** 迭代次数(默认 10000) */\n iterations?: number\n}\n\n// ─── 操作接口 ───\n\n/**\n * 非对称加密操作接口\n *\n * 通过 `crypto.asymmetric` 访问,需先调用 `crypto.init()`。\n */\nexport interface AsymmetricOperations {\n /**\n * 生成密钥对\n *\n * @returns 成功时包含公私钥对;失败时返回 KEY_GENERATION_FAILED\n */\n generateKeyPair: () => HaiResult<KeyPair>\n /**\n * 非对称加密\n *\n * @param data - 待加密明文\n * @param publicKey - 公钥(十六进制,支持带/不带 04 前缀)\n * @param options - 加密选项(密文模式、输出格式)\n * @returns 成功时返回密文字符串;失败时返回 INVALID_KEY 或 ENCRYPTION_FAILED\n */\n encrypt: (data: string, publicKey: string, options?: AsymmetricEncryptOptions) => HaiResult<string>\n /**\n * 非对称解密\n *\n * 自动检测 base64 格式输入并转换为 hex。\n *\n * @param ciphertext - 密文(hex 或 base64)\n * @param privateKey - 私钥(64 字符十六进制)\n * @param options - 解密选项(密文模式需与加密时一致)\n * @returns 成功时返回明文;失败时返回 INVALID_KEY 或 DECRYPTION_FAILED\n */\n decrypt: (ciphertext: string, privateKey: string, options?: AsymmetricEncryptOptions) => HaiResult<string>\n /**\n * 签名\n *\n * @param data - 待签名数据\n * @param privateKey - 私钥(64 字符十六进制)\n * @param options - 签名选项(hash 开关、userId)\n * @returns 成功时返回签名字符串;失败时返回 INVALID_KEY 或 SIGN_FAILED\n */\n sign: (data: string, privateKey: string, options?: SignOptions) => HaiResult<string>\n /**\n * 验签\n *\n * @param data - 原始数据\n * @param signature - 签名(需与签名时使用相同的 hash/userId 选项)\n * @param publicKey - 公钥(支持带/不带 04 前缀)\n * @param options - 验签选项\n * @returns 成功时返回 boolean;失败时返回 INVALID_KEY 或 VERIFY_FAILED\n */\n verify: (data: string, signature: string, publicKey: string, options?: SignOptions) => HaiResult<boolean>\n /**\n * 校验公钥格式是否合法\n *\n * 合法格式:128 字符十六进制(无前缀)或 130 字符(含 04 前缀)。\n */\n isValidPublicKey: (key: string) => boolean\n /**\n * 校验私钥格式是否合法\n *\n * 合法格式:64 字符十六进制。\n */\n isValidPrivateKey: (key: string) => boolean\n}\n\n/**\n * 哈希操作接口\n *\n * 通过 `crypto.hash` 访问,需先调用 `crypto.init()`。\n */\nexport interface HashOperations {\n /**\n * 计算哈希\n *\n * @param data - 待哈希数据(字符串或 Uint8Array)\n * @param options - 输入编码选项\n * @returns 成功时返回 64 字符十六进制哈希值;失败时返回 HASH_FAILED\n */\n hash: (data: string | Uint8Array, options?: HashOptions) => HaiResult<string>\n /**\n * 计算 HMAC\n *\n * 使用 HMAC 算法(RFC 2104)计算消息认证码。\n * 当密钥长度超过块大小(64 字节)时,会先对密钥进行哈希。\n *\n * @param data - 待计算数据\n * @param key - HMAC 密钥\n * @returns 成功时返回 64 字符十六进制 HMAC 值;失败时返回 HMAC_FAILED\n */\n hmac: (data: string, key: string) => HaiResult<string>\n /**\n * 验证数据的哈希是否匹配\n *\n * 比较时忽略大小写。\n *\n * @param data - 原始数据\n * @param expectedHash - 期望的哈希值\n * @returns 成功时返回 boolean;失败时返回 HASH_FAILED\n */\n verify: (data: string, expectedHash: string) => HaiResult<boolean>\n}\n\n/**\n * 对称加密操作接口\n *\n * 通过 `crypto.symmetric` 访问,需先调用 `crypto.init()`。\n * 支持 ECB/CBC 两种模式,CBC 模式需要提供 IV。\n */\nexport interface SymmetricOperations {\n /** 生成随机密钥(16 字节 = 32 个十六进制字符) */\n generateKey: () => string\n /** 生成随机 IV(16 字节 = 32 个十六进制字符) */\n generateIV: () => string\n /**\n * 对称加密\n *\n * @param data - 待加密明文\n * @param key - 密钥(32 字符十六进制)\n * @param options - 加密模式/IV/输出格式\n * @returns 成功时返回密文;失败时返回 INVALID_KEY/INVALID_IV/ENCRYPTION_FAILED\n */\n encrypt: (data: string, key: string, options?: SymmetricOptions) => HaiResult<string>\n /**\n * 对称解密\n *\n * 自动检测 base64 格式输入并转换为 hex。\n *\n * @param ciphertext - 密文(hex 或 base64)\n * @param key - 密钥(32 字符十六进制)\n * @param options - 解密模式/IV(需与加密时一致)\n * @returns 成功时返回明文;失败时返回 INVALID_KEY/INVALID_IV/DECRYPTION_FAILED\n */\n decrypt: (ciphertext: string, key: string, options?: SymmetricOptions) => HaiResult<string>\n /**\n * 带 IV 加密(CBC 模式,自动生成随机 IV)\n *\n * @param data - 待加密明文\n * @param key - 密钥(32 字符十六进制)\n * @returns 成功时返回 { ciphertext, iv };失败时同 encrypt\n */\n encryptWithIV: (data: string, key: string) => HaiResult<EncryptWithIVResult>\n /**\n * 带 IV 解密(CBC 模式)\n *\n * @param ciphertext - 密文\n * @param key - 密钥\n * @param iv - 加密时使用的 IV\n * @returns 成功时返回明文;失败时同 decrypt\n */\n decryptWithIV: (ciphertext: string, key: string, iv: string) => HaiResult<string>\n /**\n * 从密码和盐值派生密钥\n *\n * 内部使用哈希(password + salt) 取前 32 字符作为密钥。\n * 注意:此为简单派生,不适用于高安全场景。\n *\n * @param password - 密码\n * @param salt - 盐值\n * @returns 32 字符十六进制密钥\n */\n deriveKey: (password: string, salt: string) => string\n /** 校验密钥格式是否合法(32 字符十六进制) */\n isValidKey: (key: string) => boolean\n /** 校验 IV 格式是否合法(32 字符十六进制) */\n isValidIV: (iv: string) => boolean\n}\n\n/**\n * 密码哈希操作接口\n *\n * 通过 `crypto.password` 访问,需先调用 `crypto.init()`。\n * 使用迭代加盐的方式生成密码哈希。\n */\nexport interface PasswordOperations {\n /**\n * 对密码进行哈希\n *\n * 输出格式: `$hai$<iterations>$<salt>$<hash>`\n *\n * @param password - 明文密码(不能为空)\n * @param config - 可选配置(盐值长度、迭代次数)\n * @returns 成功时返回格式化的哈希字符串;失败时返回 INVALID_INPUT 或 HASH_FAILED\n */\n hash: (password: string, config?: PasswordConfig) => HaiResult<string>\n /**\n * 验证密码是否匹配\n *\n * 自动从哈希字符串中解析迭代次数和盐值进行重新计算。\n *\n * @param password - 待验证的明文密码\n * @param hash - 存储的哈希值(格式: `$hai$<iterations>$<salt>$<hash>`)\n * @returns 成功时返回 boolean;失败时返回 INVALID_INPUT 或 VERIFY_FAILED\n */\n verify: (password: string, hash: string) => HaiResult<boolean>\n}\n\n// ─── 函数接口 ───\n\n/**\n * 加密模块函数接口\n *\n * `crypto` 服务对象的类型定义。使用前必须调用 `init()` 初始化。\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n *\n * await crypto.init()\n * const hash = crypto.hash.hash('hello')\n * await crypto.close()\n * ```\n */\nexport interface CryptoFunctions {\n /**\n * 初始化加密模块\n *\n * 创建非对称/哈希/对称/密码哈希操作实例。\n * 重复调用会先关闭再重新初始化。\n *\n * @returns 成功时返回 ok(undefined);失败时返回 INIT_FAILED\n */\n init: () => Promise<HaiResult<void>>\n /**\n * 关闭加密模块,释放内部状态\n *\n * 关闭后再访问 asymmetric/hash/symmetric/password 会返回 NOT_INITIALIZED 错误。\n */\n close: () => Promise<void>\n /** 是否已初始化 */\n readonly isInitialized: boolean\n /** 非对称加密操作(未初始化时所有方法返回 NOT_INITIALIZED) */\n readonly asymmetric: AsymmetricOperations\n /** 哈希操作(未初始化时所有方法返回 NOT_INITIALIZED) */\n readonly hash: HashOperations\n /** 对称加密操作(未初始化时所有方法返回 NOT_INITIALIZED) */\n readonly symmetric: SymmetricOperations\n /** 密码哈希操作(未初始化时所有方法返回 NOT_INITIALIZED) */\n readonly password: PasswordOperations\n}\n","/**\n * @h-ai/crypto — 密码操作\n *\n * 提供迭代加盐(SM3)密码哈希与校验功能。\n * @module crypto-password\n */\n\nimport type { HaiResult } from '@h-ai/core'\n\nimport type { HashOperations, PasswordConfig, PasswordOperations } from './crypto-types.js'\nimport { core, err, ok } from '@h-ai/core'\n\nimport { cryptoM } from './crypto-i18n.js'\nimport { HaiCryptoError } from './crypto-types.js'\n\n// ─── 依赖接口 ───\n\n/** createPasswordFunctions 所需的外部依赖 */\ninterface PasswordDeps {\n /** 哈希操作实例,用于迭代哈希计算 */\n hash: HashOperations\n}\n\n// ─── 工具函数 ───\n\n/**\n * 生成加密安全的随机盐值\n *\n * 使用 Web Crypto API(crypto.getRandomValues)从大小写字母和数字中随机选取字符。\n *\n * @param length - 盐值长度(字符数)\n * @returns 随机盐值字符串\n */\nfunction generateSalt(length: number): string {\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'\n const randomBytes = new Uint8Array(length)\n globalThis.crypto.getRandomValues(randomBytes)\n let salt = ''\n for (let i = 0; i < length; i++) {\n salt += chars.charAt(randomBytes[i] % chars.length)\n }\n return salt\n}\n\n/**\n * 对数据进行多次迭代哈希(密钥拉伸)\n *\n * 首次输入为 salt + data,后续每次用前一轮的哈希结果作为输入。\n * 任一轮哈希计算失败则立即返回错误。\n *\n * @param hash - 哈希操作实例\n * @param data - 原始数据(通常为密码)\n * @param salt - 盐值\n * @param iterations - 迭代次数\n * @returns 成功时返回最终哈希值(64 字符十六进制)\n */\nfunction iterateHash(\n hash: HashOperations,\n data: string,\n salt: string,\n iterations: number,\n): HaiResult<string> {\n let current = salt + data\n for (let i = 0; i < iterations; i++) {\n const result = hash.hash(current)\n if (!result.success) {\n return result\n }\n current = result.data\n }\n return ok(current)\n}\n\n// ─── 密码操作工厂 ───\n\n/**\n * 创建密码哈希操作实例\n *\n * 内部使用迭代加盐的方式生成密码哈希,格式为 `$hai$<iterations>$<salt>$<hash>`。\n *\n * @param deps - 依赖(需要注入哈希操作实例)\n * @returns PasswordOperations 接口实现\n */\nexport function createPasswordFunctions(deps: PasswordDeps): PasswordOperations {\n const { hash: hashOps } = deps\n\n return {\n /**\n * 对密码进行迭代加盐哈希\n *\n * 输出格式: `$hai$<iterations>$<salt>$<hash>`\n *\n * @param password - 明文密码(不能为空)\n * @param config - 可选配置(盐值长度、迭代次数)\n * @returns 成功时返回格式化的哈希字符串;失败时返回 INVALID_INPUT 或 HASH_FAILED\n */\n hash(password: string, config: PasswordConfig = {}): HaiResult<string> {\n const { saltLength = 16, iterations = 10000 } = config\n\n try {\n if (!password) {\n return err(\n HaiCryptoError.INVALID_INPUT,\n cryptoM('crypto_passwordEmpty'),\n )\n }\n\n const salt = generateSalt(saltLength)\n const hashResult = iterateHash(hashOps, password, salt, iterations)\n if (!hashResult.success) {\n return hashResult\n }\n\n const formatted = `$hai$${iterations}$${salt}$${hashResult.data}`\n return ok(formatted)\n }\n catch (error) {\n return err(\n HaiCryptoError.HASH_FAILED,\n cryptoM('crypto_passwordHashFailed'),\n error,\n )\n }\n },\n\n /**\n * 验证密码是否匹配已存储的哈希\n *\n * 从哈希字符串中解析迭代次数和盐值,重新计算后比较。\n * 格式要求: `$hai$<iterations>$<salt>$<hash>`\n *\n * @param password - 待验证的明文密码\n * @param hash - 存储的哈希值\n * @returns 成功时返回 boolean;失败时返回 INVALID_INPUT 或 VERIFY_FAILED\n */\n verify(password: string, hash: string): HaiResult<boolean> {\n try {\n if (!password || !hash) {\n return err(\n HaiCryptoError.INVALID_INPUT,\n cryptoM('crypto_passwordHashEmpty'),\n )\n }\n\n const parts = hash.split('$')\n if (parts.length !== 5 || parts[1] !== 'hai') {\n return err(\n HaiCryptoError.INVALID_INPUT,\n cryptoM('crypto_hashFormatInvalid'),\n )\n }\n\n const storedIterations = Number.parseInt(parts[2], 10)\n const salt = parts[3]\n const storedHash = parts[4]\n\n if (Number.isNaN(storedIterations) || !salt || !storedHash) {\n return err(\n HaiCryptoError.INVALID_INPUT,\n cryptoM('crypto_hashFormatInvalid'),\n )\n }\n\n const hashResult = iterateHash(hashOps, password, salt, storedIterations)\n if (!hashResult.success) {\n return hashResult\n }\n\n return ok(core.string.constantTimeEqual(hashResult.data, storedHash))\n }\n catch (error) {\n return err(\n HaiCryptoError.VERIFY_FAILED,\n cryptoM('crypto_passwordVerifyFailed'),\n error,\n )\n }\n },\n }\n}\n","/**\n * @h-ai/crypto — 内部工具函数\n *\n * 提供 SM2/SM4 共用的编码转换辅助函数。 仅供模块内部使用,不对外导出。\n * @module crypto-utils\n */\n\n/**\n * 判断字符串是否为 Base64 格式\n *\n * 使用简单启发式:包含 +、/ 或以 = 结尾视为 base64。\n *\n * @param str - 待检测字符串\n */\nexport function isBase64(str: string): boolean {\n return str.includes('+') || str.includes('/') || str.endsWith('=')\n}\n\n/**\n * Hex 字符串转 Base64 编码\n *\n * 使用 Web 标准 API btoa,前后端通用(Node 16+ / 所有现代浏览器)。\n *\n * @param hex - 十六进制字符串(长度必须为偶数)\n * @returns Base64 编码字符串\n */\nexport function hexToBase64(hex: string): string {\n const bytes = new Uint8Array(hex.length / 2)\n for (let i = 0; i < hex.length; i += 2) {\n bytes[i / 2] = Number.parseInt(hex.slice(i, i + 2), 16)\n }\n return btoa(String.fromCharCode(...bytes))\n}\n\n/**\n * Base64 编码转 Hex 字符串\n *\n * 使用 Web 标准 API atob,前后端通用(Node 16+ / 所有现代浏览器)。\n *\n * @param base64 - Base64 编码字符串\n * @returns 小写十六进制字符串\n */\nexport function base64ToHex(base64: string): string {\n const binary = atob(base64)\n const bytes = new Uint8Array(binary.length)\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i)\n }\n return Array.from(bytes)\n .map(b => b.toString(16).padStart(2, '0'))\n .join('')\n}\n","/**\n * @h-ai/crypto — SM2 非对称加密\n *\n * 提供 SM2 密钥对生成、加解密、签名与验签操作。\n * @module crypto-sm2\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { AsymmetricEncryptOptions, AsymmetricOperations, KeyPair, SignOptions } from './crypto-types.js'\n\nimport { err, ok } from '@h-ai/core'\n// @ts-expect-error sm-crypto 无类型定义\nimport smCrypto from 'sm-crypto'\n\nimport { cryptoM } from './crypto-i18n.js'\nimport {\n\n HaiCryptoError,\n\n} from './crypto-types.js'\nimport { base64ToHex, hexToBase64, isBase64 } from './crypto-utils.js'\n\nconst { sm2 } = smCrypto\n\n// ─── SM2 算法实现 ───\n\n/**\n * 创建 SM2 算法操作实例\n *\n * 基于 sm-crypto 库实现 SM2 非对称加密、签名与验签。\n * 公钥支持带/不带 04 前缀两种格式(内部统一补齐)。\n * 密文支持 hex/base64 两种格式(解密时自动检测)。\n *\n * @returns AsymmetricOperations 接口实现\n */\nexport function createSM2(): AsymmetricOperations {\n return {\n /**\n * 生成 SM2 密钥对\n *\n * @returns 成功时返回包含公钥(130 字符含 04 前缀)和私钥(64 字符)的密钥对\n */\n generateKeyPair(): HaiResult<KeyPair> {\n try {\n const keyPair = sm2.generateKeyPairHex()\n return ok({\n publicKey: keyPair.publicKey,\n privateKey: keyPair.privateKey,\n })\n }\n catch (error) {\n return err(\n HaiCryptoError.KEY_GENERATION_FAILED,\n cryptoM('crypto_sm2KeyPairGenerateFailed', { params: { error: error instanceof Error ? error.message : String(error) } }),\n error,\n )\n }\n },\n\n /**\n * SM2 非对称加密\n *\n * 公钥自动补齐 04 前缀;支持 hex/base64 输出。\n *\n * @param data - 待加密明文\n * @param publicKey - 公钥(支持带/不带 04 前缀)\n * @param options - 加密选项(密文模式、输出格式)\n * @returns 成功时返回密文;失败时返回 INVALID_KEY 或 ENCRYPTION_FAILED\n */\n encrypt(\n data: string,\n publicKey: string,\n options: AsymmetricEncryptOptions = {},\n ): HaiResult<string> {\n const { cipherMode = 1, outputFormat = 'hex' } = options\n\n if (!this.isValidPublicKey(publicKey)) {\n return err(\n HaiCryptoError.INVALID_KEY,\n cryptoM('crypto_sm2PublicKeyInvalid'),\n )\n }\n\n try {\n // 确保公钥带 04 前缀\n const key = publicKey.startsWith('04') ? publicKey : `04${publicKey}`\n const encrypted = sm2.doEncrypt(data, key, cipherMode)\n\n if (!encrypted) {\n return err(\n HaiCryptoError.ENCRYPTION_FAILED,\n cryptoM('crypto_sm2EncryptEmpty'),\n )\n }\n\n if (outputFormat === 'base64') {\n return ok(hexToBase64(encrypted))\n }\n\n return ok(encrypted)\n }\n catch (error) {\n return err(\n HaiCryptoError.ENCRYPTION_FAILED,\n cryptoM('crypto_sm2EncryptFailed', { params: { error: error instanceof Error ? error.message : String(error) } }),\n error,\n )\n }\n },\n\n /**\n * SM2 非对称解密\n *\n * 自动检测 base64 格式输入并转换为 hex 后解密。\n *\n * @param ciphertext - 密文(hex 或 base64)\n * @param privateKey - 私钥(64 字符十六进制)\n * @param options - 解密选项(密文模式需与加密时一致)\n * @returns 成功时返回明文;失败时返回 INVALID_KEY 或 DECRYPTION_FAILED\n */\n decrypt(\n ciphertext: string,\n privateKey: string,\n options: AsymmetricEncryptOptions = {},\n ): HaiResult<string> {\n const { cipherMode = 1 } = options\n\n if (!this.isValidPrivateKey(privateKey)) {\n return err(\n HaiCryptoError.INVALID_KEY,\n cryptoM('crypto_sm2PrivateKeyInvalid'),\n )\n }\n\n try {\n // 自动检测并转换 base64 格式\n let input = ciphertext\n if (isBase64(ciphertext)) {\n input = base64ToHex(ciphertext)\n }\n\n const decrypted = sm2.doDecrypt(input, privateKey, cipherMode)\n\n if (decrypted === false || decrypted === null || decrypted === undefined) {\n return err(\n HaiCryptoError.DECRYPTION_FAILED,\n cryptoM('crypto_sm2DecryptFailed'),\n )\n }\n\n return ok(decrypted)\n }\n catch (error) {\n return err(\n HaiCryptoError.DECRYPTION_FAILED,\n cryptoM('crypto_sm2DecryptFailedWithError', { params: { error: error instanceof Error ? error.message : String(error) } }),\n error,\n )\n }\n },\n\n /**\n * SM2 数字签名\n *\n * 默认对数据先做哈希(hash=true),使用 userId 作为签名附加参数。\n *\n * @param data - 待签名数据\n * @param privateKey - 私钥(64 字符十六进制)\n * @param options - 签名选项(hash 开关、userId)\n * @returns 成功时返回签名字符串;失败时返回 INVALID_KEY 或 SIGN_FAILED\n */\n sign(\n data: string,\n privateKey: string,\n options: SignOptions = {},\n ): HaiResult<string> {\n const { hash = true, userId = '1234567812345678' } = options\n\n if (!this.isValidPrivateKey(privateKey)) {\n return err(\n HaiCryptoError.INVALID_KEY,\n cryptoM('crypto_sm2PrivateKeyInvalid'),\n )\n }\n\n try {\n const signature = sm2.doSignature(data, privateKey, { hash, userId })\n\n if (!signature) {\n return err(\n HaiCryptoError.SIGN_FAILED,\n cryptoM('crypto_sm2SignEmpty'),\n )\n }\n\n return ok(signature)\n }\n catch (error) {\n return err(\n HaiCryptoError.SIGN_FAILED,\n cryptoM('crypto_sm2SignFailed', { params: { error: error instanceof Error ? error.message : String(error) } }),\n error,\n )\n }\n },\n\n /**\n * SM2 签名验证\n *\n * 公钥自动补齐 04 前缀;hash/userId 需与签名时一致。\n *\n * @param data - 原始数据\n * @param signature - 签名值\n * @param publicKey - 公钥(支持带/不带 04 前缀)\n * @param options - 验签选项(hash 开关、userId)\n * @returns 成功时返回 boolean;失败时返回 INVALID_KEY 或 VERIFY_FAILED\n */\n verify(\n data: string,\n signature: string,\n publicKey: string,\n options: SignOptions = {},\n ): HaiResult<boolean> {\n const { hash = true, userId = '1234567812345678' } = options\n\n if (!this.isValidPublicKey(publicKey)) {\n return err(\n HaiCryptoError.INVALID_KEY,\n cryptoM('crypto_sm2PublicKeyInvalid'),\n )\n }\n\n try {\n // 确保公钥带 04 前缀\n const key = publicKey.startsWith('04') ? publicKey : `04${publicKey}`\n const isValid = sm2.doVerifySignature(data, signature, key, { hash, userId })\n return ok(!!isValid)\n }\n catch (error) {\n return err(\n HaiCryptoError.VERIFY_FAILED,\n cryptoM('crypto_sm2VerifyFailed', { params: { error: error instanceof Error ? error.message : String(error) } }),\n error,\n )\n }\n },\n\n /**\n * 校验公钥格式是否合法\n *\n * 合法格式:128 字符十六进制(无前缀)或 130 字符(含 04 前缀)。\n *\n * @param key - 待校验公钥\n * @returns 格式合法返回 true\n */\n isValidPublicKey(key: string): boolean {\n if (!key || typeof key !== 'string')\n return false\n // 公钥长度:无前缀 128 字符,带 04 前缀 130 字符\n const cleanKey = key.startsWith('04') ? key.slice(2) : key\n return /^[0-9a-f]{128}$/i.test(cleanKey)\n },\n\n /**\n * 校验私钥格式是否合法\n *\n * 合法格式:64 字符十六进制。\n *\n * @param key - 待校验私钥\n * @returns 格式合法返回 true\n */\n isValidPrivateKey(key: string): boolean {\n if (!key || typeof key !== 'string')\n return false\n // 私钥长度:64 字符\n return /^[0-9a-f]{64}$/i.test(key)\n },\n }\n}\n","/**\n * @h-ai/crypto — SM3 哈希\n *\n * 提供 SM3 消息摘要与 HMAC 操作。\n * @module crypto-sm3\n */\n\nimport type { HaiResult } from '@h-ai/core'\n\nimport type { HashOperations, HashOptions } from './crypto-types.js'\nimport { core, err, ok } from '@h-ai/core'\n// @ts-expect-error sm-crypto 无类型定义\nimport smCrypto from 'sm-crypto'\n\nimport { cryptoM } from './crypto-i18n.js'\nimport {\n HaiCryptoError,\n\n} from './crypto-types.js'\n\nconst { sm3 } = smCrypto\n\n// ─── SM3 算法实现 ───\n\n/**\n * 创建 SM3 算法操作实例\n *\n * 基于 sm-crypto 库实现 SM3 哈希、HMAC 与哈希验证。\n * 支持字符串(UTF-8/Hex)和 Uint8Array 输入。\n * HMAC 实现遵循 RFC 2104 标准。\n *\n * @returns HashOperations 接口实现\n */\nexport function createSM3(): HashOperations {\n return {\n /**\n * 计算 SM3 哈希\n *\n * 支持字符串(UTF-8/Hex)和 Uint8Array 输入。\n *\n * @param data - 待哈希数据\n * @param options - 输入编码与输出格式\n * @returns 成功时返回 64 字符十六进制哈希值;失败时返回 HASH_FAILED\n */\n hash(\n data: string | Uint8Array,\n options: HashOptions = {},\n ): HaiResult<string> {\n const { inputEncoding = 'utf8' } = options\n\n try {\n let input: string | number[]\n\n if (data instanceof Uint8Array) {\n // Uint8Array 转为数字数组(sm-crypto 支持的格式)\n input = Array.from(data)\n }\n else if (inputEncoding === 'hex') {\n // 十六进制字符串转为数字数组\n input = hexToBytes(data)\n }\n else {\n // UTF-8 字符串直接传入\n input = data\n }\n\n const result = sm3(input)\n\n if (!result) {\n return err(\n HaiCryptoError.HASH_FAILED,\n cryptoM('crypto_sm3HashEmpty'),\n )\n }\n\n return ok(result)\n }\n catch (error) {\n return err(\n HaiCryptoError.HASH_FAILED,\n cryptoM('crypto_sm3HashFailed', { params: { error: error instanceof Error ? error.message : String(error) } }),\n error,\n )\n }\n },\n\n /**\n * 计算 HMAC-SM3 消息认证码\n *\n * 实现遵循 RFC 2104;密钥超过块大小(64 字节)时先对密钥做哈希。\n *\n * @param data - 待计算数据\n * @param key - HMAC 密钥\n * @returns 成功时返回 64 字符十六进制 HMAC 值;失败时返回 HMAC_FAILED\n */\n hmac(data: string, key: string): HaiResult<string> {\n try {\n const blockSize = 64\n const opad = 0x5C\n const ipad = 0x36\n\n // 处理密钥\n let keyBytes: number[]\n if (key.length > blockSize) {\n const hashedKey = sm3(key)\n keyBytes = hexToBytes(hashedKey)\n }\n else {\n keyBytes = stringToBytes(key)\n }\n\n // 填充密钥到块大小\n while (keyBytes.length < blockSize) {\n keyBytes.push(0)\n }\n\n // 计算 iKeyPad 和 oKeyPad\n const iKeyPad = keyBytes.map(b => b ^ ipad)\n const oKeyPad = keyBytes.map(b => b ^ opad)\n\n // 计算内层哈希:H(iKeyPad || data)\n const innerInput = iKeyPad.concat(stringToBytes(data))\n const innerHash = sm3(innerInput)\n\n // 计算外层哈希:H(oKeyPad || innerHash)\n const outerInput = oKeyPad.concat(hexToBytes(innerHash))\n const result = sm3(outerInput)\n\n return ok(result)\n }\n catch (error) {\n return err(\n HaiCryptoError.HMAC_FAILED,\n cryptoM('crypto_sm3HmacFailed', { params: { error: error instanceof Error ? error.message : String(error) } }),\n error,\n )\n }\n },\n\n /**\n * 验证数据的哈希是否匹配\n *\n * 对数据做 SM3 哈希后与期望值比较(忽略大小写)。\n *\n * @param data - 原始数据\n * @param expectedHash - 期望的哈希值\n * @returns 成功时返回 boolean;失败时返回 HASH_FAILED\n */\n verify(data: string, expectedHash: string): HaiResult<boolean> {\n try {\n const hashResult = sm3(data)\n return ok(core.string.constantTimeEqual(hashResult.toLowerCase(), expectedHash.toLowerCase()))\n }\n catch (error) {\n return err(\n HaiCryptoError.HASH_FAILED,\n cryptoM('crypto_sm3VerifyFailed', { params: { error: error instanceof Error ? error.message : String(error) } }),\n error,\n )\n }\n },\n }\n}\n\n// ─── 辅助函数 ───\n\n/**\n * 十六进制字符串转字节数组\n *\n * @param hex - 十六进制字符串(长度必须为偶数)\n * @returns 字节数组\n */\nfunction hexToBytes(hex: string): number[] {\n const bytes: number[] = []\n for (let i = 0; i < hex.length; i += 2) {\n bytes.push(Number.parseInt(hex.slice(i, i + 2), 16))\n }\n return bytes\n}\n\n/**\n * UTF-8 字符串转字节数组\n *\n * 使用 TextEncoder 进行编码转换。\n *\n * @param str - UTF-8 字符串\n * @returns 字节数组\n */\nfunction stringToBytes(str: string): number[] {\n const encoder = new TextEncoder()\n return Array.from(encoder.encode(str))\n}\n","/**\n * @h-ai/crypto — SM4 对称加密\n *\n * 提供 SM4 对称加解密操作(CBC/ECB 模式)。\n * @module crypto-sm4\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { EncryptWithIVResult, SymmetricOperations, SymmetricOptions } from './crypto-types.js'\n\nimport { err, ok } from '@h-ai/core'\n// @ts-expect-error sm-crypto 无类型定义\nimport smCrypto from 'sm-crypto'\n\nimport { cryptoM } from './crypto-i18n.js'\nimport {\n\n HaiCryptoError,\n\n} from './crypto-types.js'\nimport { base64ToHex, hexToBase64, isBase64 } from './crypto-utils.js'\n\nconst { sm3, sm4 } = smCrypto\n\n// ─── SM4 算法实现 ───\n\n/**\n * 创建 SM4 算法操作实例\n *\n * 基于 sm-crypto 库实现 SM4 对称加密/解密。\n * 支持 ECB(默认)和 CBC 两种模式,使用 PKCS#7 填充。\n * 密文支持 hex/base64 两种格式(解密时自动检测)。\n *\n * @returns SymmetricOperations 接口实现\n */\nexport function createSM4(): SymmetricOperations {\n return {\n /** 生成随机密钥(16 字节 = 32 个十六进制字符) */\n generateKey(): string {\n return generateRandomHex(16)\n },\n\n /** 生成随机 IV(16 字节 = 32 个十六进制字符) */\n generateIV(): string {\n return generateRandomHex(16)\n },\n\n /**\n * SM4 对称加密\n *\n * 支持 ECB(默认)和 CBC 两种模式,使用 PKCS#7 填充。\n * CBC 模式需提供合法 IV。\n *\n * @param data - 待加密明文\n * @param key - 密钥(32 字符十六进制)\n * @param options - 加密模式/IV/输出格式\n * @returns 成功时返回密文;失败时返回 INVALID_KEY/INVALID_IV/ENCRYPTION_FAILED\n */\n encrypt(\n data: string,\n key: string,\n options: SymmetricOptions = {},\n ): HaiResult<string> {\n const {\n mode = 'ecb',\n iv,\n outputFormat = 'hex',\n } = options\n\n if (!this.isValidKey(key)) {\n return err(\n HaiCryptoError.INVALID_KEY,\n cryptoM('crypto_sm4KeyInvalid'),\n )\n }\n\n if (mode === 'cbc' && !iv) {\n return err(\n HaiCryptoError.INVALID_IV,\n cryptoM('crypto_sm4CbcNeedIv'),\n )\n }\n\n if (mode === 'cbc' && iv && !this.isValidIV(iv)) {\n return err(\n HaiCryptoError.INVALID_IV,\n cryptoM('crypto_sm4IvInvalid'),\n )\n }\n\n try {\n const sm4Options: Record<string, unknown> = {\n mode,\n padding: 'pkcs#7',\n }\n\n if (mode === 'cbc' && iv) {\n sm4Options.iv = iv\n }\n\n const encrypted = sm4.encrypt(data, key, sm4Options)\n\n if (!encrypted) {\n return err(\n HaiCryptoError.ENCRYPTION_FAILED,\n cryptoM('crypto_sm4EncryptEmpty'),\n )\n }\n\n if (outputFormat === 'base64') {\n return ok(hexToBase64(encrypted))\n }\n\n return ok(encrypted)\n }\n catch (error) {\n return err(\n HaiCryptoError.ENCRYPTION_FAILED,\n cryptoM('crypto_sm4EncryptFailed', { params: { error: error instanceof Error ? error.message : String(error) } }),\n error,\n )\n }\n },\n\n /**\n * SM4 对称解密\n *\n * 自动检测 base64 格式输入并转换为 hex。\n * 解密模式和 IV 需与加密时一致。\n *\n * @param ciphertext - 密文(hex 或 base64)\n * @param key - 密钥(32 字符十六进制)\n * @param options - 解密模式/IV\n * @returns 成功时返回明文;失败时返回 INVALID_KEY/INVALID_IV/DECRYPTION_FAILED\n */\n decrypt(\n ciphertext: string,\n key: string,\n options: SymmetricOptions = {},\n ): HaiResult<string> {\n const { mode = 'ecb', iv } = options\n\n if (!this.isValidKey(key)) {\n return err(\n HaiCryptoError.INVALID_KEY,\n cryptoM('crypto_sm4KeyInvalid'),\n )\n }\n\n if (mode === 'cbc' && !iv) {\n return err(\n HaiCryptoError.INVALID_IV,\n cryptoM('crypto_sm4CbcNeedIv'),\n )\n }\n\n try {\n // 自动检测并转换 base64 格式\n let input = ciphertext\n if (isBase64(ciphertext)) {\n input = base64ToHex(ciphertext)\n }\n\n const sm4Options: Record<string, unknown> = {\n mode,\n padding: 'pkcs#7',\n }\n\n if (mode === 'cbc' && iv) {\n sm4Options.iv = iv\n }\n\n const decrypted = sm4.decrypt(input, key, sm4Options)\n\n if (decrypted === false || decrypted === null || decrypted === undefined) {\n return err(\n HaiCryptoError.DECRYPTION_FAILED,\n cryptoM('crypto_sm4DecryptFailed'),\n )\n }\n\n return ok(decrypted)\n }\n catch (error) {\n return err(\n HaiCryptoError.DECRYPTION_FAILED,\n cryptoM('crypto_sm4DecryptFailedWithError', { params: { error: error instanceof Error ? error.message : String(error) } }),\n error,\n )\n }\n },\n\n /**\n * 带 IV 加密(CBC 模式,自动生成随机 IV)\n *\n * @param data - 待加密明文\n * @param key - 密钥(32 字符十六进制)\n * @returns 成功时返回 { ciphertext, iv };失败时同 encrypt\n */\n encryptWithIV(\n data: string,\n key: string,\n ): HaiResult<EncryptWithIVResult> {\n const iv = this.generateIV()\n const result = this.encrypt(data, key, { mode: 'cbc', iv })\n\n if (!result.success) {\n return result\n }\n\n return ok({ ciphertext: result.data, iv })\n },\n\n /**\n * 带 IV 解密(CBC 模式)\n *\n * @param ciphertext - 密文\n * @param key - 密钥\n * @param iv - 加密时使用的 IV\n * @returns 成功时返回明文;失败时同 decrypt\n */\n decryptWithIV(\n ciphertext: string,\n key: string,\n iv: string,\n ): HaiResult<string> {\n return this.decrypt(ciphertext, key, { mode: 'cbc', iv })\n },\n\n /**\n * 从密码和盐值派生密钥\n *\n * 内部使用 SM3 哈希(password + salt) 取前 32 字符作为密钥。\n * 注意:此为简单派生,不适用于高安全场景。\n *\n * @param password - 密码\n * @param salt - 盐值\n * @returns 32 字符十六进制密钥\n */\n deriveKey(password: string, salt: string): string {\n const combined = password + salt\n const hash = sm3(combined)\n // 取前 32 个十六进制字符(16 字节)\n return hash.slice(0, 32)\n },\n\n /** 校验密钥格式是否合法(32 字符十六进制) */\n isValidKey(key: string): boolean {\n return /^[0-9a-f]{32}$/i.test(key)\n },\n\n /** 校验 IV 格式是否合法(32 字符十六进制) */\n isValidIV(iv: string): boolean {\n return /^[0-9a-f]{32}$/i.test(iv)\n },\n }\n}\n\n// ─── 辅助函数 ───\n\n/**\n * 生成加密安全的随机十六进制字符串\n *\n * 使用 Web Crypto API(crypto.getRandomValues),前后端通用。\n *\n * @param byteLength - 字节数(输出字符数为 byteLength × 2)\n * @returns 小写十六进制字符串\n */\nfunction generateRandomHex(byteLength: number): string {\n const bytes = new Uint8Array(byteLength)\n // Web Crypto API,前后端通用\n crypto.getRandomValues(bytes)\n return Array.from(bytes)\n .map(b => b.toString(16).padStart(2, '0'))\n .join('')\n}\n","/**\n * @h-ai/crypto — 加密服务主入口\n *\n * 提供统一的 `crypto` 对象,聚合所有结构化加密操作。\n * @module crypto-main\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { AsymmetricOperations, CryptoFunctions, HashOperations, PasswordOperations, SymmetricOperations } from './crypto-types.js'\n\nimport { core, err, ok } from '@h-ai/core'\n\nimport { cryptoM } from './crypto-i18n.js'\nimport { createPasswordFunctions } from './crypto-password.js'\nimport { createSM2 } from './crypto-sm2.js'\nimport { createSM3 } from './crypto-sm3.js'\nimport { createSM4 } from './crypto-sm4.js'\nimport {\n\n HaiCryptoError,\n\n} from './crypto-types.js'\n\nconst logger = core.logger.child({ module: 'crypto', scope: 'main' })\n\n// ─── 内部状态 ───\n\n/** 是否已初始化 */\nlet initialized = false\n/** 并发初始化防护标志 */\nlet initInProgress = false\n/** 当前非对称加密操作实例 */\nlet currentAsymmetric: AsymmetricOperations | null = null\n/** 当前哈希操作实例 */\nlet currentHash: HashOperations | null = null\n/** 当前对称加密操作实例 */\nlet currentSymmetric: SymmetricOperations | null = null\n/** 当前密码哈希操作实例 */\nlet currentPassword: PasswordOperations | null = null\n\n// ─── 未初始化占位 ───\n\nconst notInitialized = core.module.createNotInitializedKit(\n HaiCryptoError.NOT_INITIALIZED,\n () => cryptoM('crypto_notInitialized'),\n)\n\nconst notInitializedAsymmetric = notInitialized.proxy<AsymmetricOperations>('sync')\nconst notInitializedHash = notInitialized.proxy<HashOperations>('sync')\nconst notInitializedSymmetric = notInitialized.proxy<SymmetricOperations>('sync')\nconst notInitializedPassword = notInitialized.proxy<PasswordOperations>('sync')\n\n// ─── 服务对象 ───\n\n/**\n * 加密模块服务对象(统一入口)\n *\n * 使用前必须调用 `crypto.init()` 进行初始化。\n * 未初始化时访问 asymmetric/hash/symmetric/password 的任何方法均返回 NOT_INITIALIZED 错误。\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n *\n * await crypto.init()\n * const hash = crypto.hash.hash('hello')\n * const keyPair = crypto.asymmetric.generateKeyPair()\n * await crypto.close()\n * ```\n */\nexport const crypto: CryptoFunctions = {\n /**\n * 初始化加密模块\n *\n * 创建非对称/哈希/对称/密码哈希操作实例。\n * 重复调用会先关闭再重新初始化。\n *\n * @returns 成功时返回 ok(undefined);失败时返回 INIT_FAILED\n */\n async init(): Promise<HaiResult<void>> {\n // 并发初始化防护:避免多次 init 同时执行导致资源泄漏\n if (initInProgress) {\n logger.warn('Crypto init already in progress, skipping concurrent call')\n return err(\n HaiCryptoError.INIT_FAILED,\n cryptoM('crypto_initFailed', { params: { error: 'Concurrent initialization detected' } }),\n )\n }\n initInProgress = true\n\n try {\n if (initialized) {\n logger.warn('Crypto module is already initialized, reinitializing')\n await crypto.close()\n }\n\n logger.info('Initializing crypto module')\n\n currentAsymmetric = createSM2()\n currentHash = createSM3()\n currentSymmetric = createSM4()\n currentPassword = createPasswordFunctions({ hash: currentHash })\n initialized = true\n logger.info('Crypto module initialized')\n return ok(undefined)\n }\n catch (error) {\n // 清理部分赋值的状态\n currentAsymmetric = null\n currentHash = null\n currentSymmetric = null\n currentPassword = null\n initialized = false\n logger.error('Crypto module initialization failed', { error })\n return err(\n HaiCryptoError.INIT_FAILED,\n cryptoM('crypto_initFailed', {\n params: { error: error instanceof Error ? error.message : String(error) },\n }),\n error,\n )\n }\n finally {\n initInProgress = false\n }\n },\n\n /** 非对称加密操作(未初始化时所有方法返回 NOT_INITIALIZED) */\n get asymmetric(): AsymmetricOperations { return currentAsymmetric ?? notInitializedAsymmetric },\n /** 哈希操作(未初始化时所有方法返回 NOT_INITIALIZED) */\n get hash(): HashOperations { return currentHash ?? notInitializedHash },\n /** 对称加密操作(未初始化时所有方法返回 NOT_INITIALIZED) */\n get symmetric(): SymmetricOperations { return currentSymmetric ?? notInitializedSymmetric },\n /** 密码哈希操作(未初始化时所有方法返回 NOT_INITIALIZED) */\n get password(): PasswordOperations { return currentPassword ?? notInitializedPassword },\n /** 是否已初始化 */\n get isInitialized() { return initialized },\n\n /**\n * 关闭加密模块,释放内部状态\n *\n * 关闭后访问 asymmetric/hash/symmetric/password 会返回 NOT_INITIALIZED 错误。\n */\n async close() {\n if (!initialized) {\n logger.info('Crypto module already closed, skipping')\n return\n }\n\n logger.info('Closing crypto module')\n\n currentAsymmetric = null\n currentHash = null\n currentSymmetric = null\n currentPassword = null\n initialized = false\n\n logger.info('Crypto module closed')\n },\n}\n"]}
1
+ {"version":3,"sources":["../messages/en-US.json","../messages/ja-JP.json","../messages/zh-CN.json","../src/crypto-i18n.ts","../src/crypto-types.ts","../src/crypto-password.ts","../src/crypto-public-key.ts","../src/crypto-utils.ts","../src/crypto-sm2.ts","../src/crypto-sm3.ts","../src/crypto-sm4.ts","../src/transport/crypto-transport-body.ts","../src/transport/crypto-transport-types.ts","../src/transport/crypto-transport-codec.ts","../src/transport/crypto-transport-error.ts","../src/transport/crypto-transport-client.ts","../src/transport/crypto-transport-keyring.ts","../src/transport/crypto-transport-server.ts","../src/crypto-main.ts","../src/transport/crypto-transport-request.ts","../src/transport/store-provider/crypto-transport-store-memory.ts","../src/transport/store-provider/crypto-transport-store-redis.ts","../src/transport/store-provider/crypto-transport-store-reldb.ts"],"names":["core","smCrypto","ok","err","method","HaiCommonError","crypto","id","createClientId","toOperationError","unwrapResult"],"mappings":"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","file":"index.js","sourcesContent":["{\n \"$schema\": \"https://inlang.com/schema/inlang-message-format\",\n \"crypto_notInitialized\": \"Crypto module not initialized, call crypto.init() first\",\n \"crypto_initFailed\": \"Crypto module initialization failed: {error}\",\n \"crypto_sm2PublicKeyInvalid\": \"Invalid SM2 public key format\",\n \"crypto_sm2PrivateKeyInvalid\": \"Invalid SM2 private key format\",\n \"crypto_sm2EncryptEmpty\": \"SM2 encryption returned empty result\",\n \"crypto_sm2DecryptFailed\": \"SM2 decryption failed or returned invalid result\",\n \"crypto_sm2SignEmpty\": \"SM2 signature returned empty result\",\n \"crypto_sm2KeyPairGenerateFailed\": \"SM2 key pair generation failed: {error}\",\n \"crypto_sm2EncryptFailed\": \"SM2 encryption failed: {error}\",\n \"crypto_sm2DecryptFailedWithError\": \"SM2 decryption failed: {error}\",\n \"crypto_sm2SignFailed\": \"SM2 signing failed: {error}\",\n \"crypto_sm2VerifyFailed\": \"SM2 verification failed: {error}\",\n \"crypto_sm3HashEmpty\": \"SM3 hash returned empty result\",\n \"crypto_sm3HashFailed\": \"SM3 hash calculation failed: {error}\",\n \"crypto_sm3HmacFailed\": \"HMAC-SM3 calculation failed: {error}\",\n \"crypto_sm3VerifyFailed\": \"SM3 hash verification failed: {error}\",\n \"crypto_sm4KeyInvalid\": \"SM4 key must be 16 bytes (32 hex characters)\",\n \"crypto_sm4CbcNeedIv\": \"CBC mode requires IV\",\n \"crypto_sm4IvInvalid\": \"SM4 IV must be 16 bytes (32 hex characters)\",\n \"crypto_sm4EncryptEmpty\": \"SM4 encryption returned empty result\",\n \"crypto_sm4DecryptFailed\": \"SM4 decryption failed\",\n \"crypto_sm4EncryptFailed\": \"SM4 encryption failed: {error}\",\n \"crypto_sm4DecryptFailedWithError\": \"SM4 decryption failed: {error}\",\n \"crypto_passwordEmpty\": \"Password cannot be empty\",\n \"crypto_passwordHashEmpty\": \"Password and hash cannot be empty\",\n \"crypto_passwordHashFailed\": \"Password hashing failed\",\n \"crypto_hashFormatInvalid\": \"Invalid hash format\",\n \"crypto_passwordVerifyFailed\": \"Password verification failed\",\n \"crypto_transportClientKeyGenerateFailed\": \"Failed to generate transport client key pair\",\n \"crypto_transportServerKeyRingInvalid\": \"The server transport key ring is missing or invalid. Check that private HAI_CRYPTO_TRANSPORT_SERVERKEYRING contains complete valid JSON and distribute the same ring to every node.\",\n \"crypto_transportServerKeyUnknown\": \"Transport server key version is unknown or revoked\",\n \"crypto_transportKeyStoreRequired\": \"Transport encryption requires an explicit client public key store\",\n \"crypto_transportKeyStoreTtlInvalid\": \"Public-key store TTL must be an integer between 1 and 2147483647 seconds\",\n \"crypto_transportKeyStoreCapacityInvalid\": \"Public-key store capacity must be a positive safe integer\",\n \"crypto_transportKeyStoreCapacityMismatch\": \"Public-key store shared capacity settings do not match\",\n \"crypto_transportKeyStoreCapacityReached\": \"Public-key store capacity has been reached\",\n \"crypto_transportKeyStoreOperationFailed\": \"Public-key store operation failed\",\n \"crypto_transportAuthenticationFailed\": \"Transport authentication, request binding or replay validation failed\",\n \"crypto_transportKeyExchangeRequestFailed\": \"Transport key exchange request failed\",\n \"crypto_transportKeyExchangeHttpFailed\": \"Transport key exchange returned HTTP {status}\",\n \"crypto_transportKeyExchangeInvalidJson\": \"Transport key exchange response is not valid JSON\",\n \"crypto_transportKeyExchangeMissingFields\": \"Transport key exchange response is missing required fields\",\n \"crypto_transportClientNotInitialized\": \"Transport client has not completed key exchange\",\n \"crypto_transportClientNotRegistered\": \"Transport client is not registered or has expired\",\n \"crypto_transportRequestEncryptFailed\": \"Failed to encrypt transport request body\",\n \"crypto_transportRequestDecryptFailed\": \"Failed to decrypt transport request body\",\n \"crypto_transportResponseEncryptFailed\": \"Failed to encrypt transport response body\",\n \"crypto_transportResponseDecryptFailed\": \"Failed to decrypt transport response body\",\n \"crypto_transportSessionKeyEncryptFailed\": \"Failed to encrypt transport session key\",\n \"crypto_transportSessionKeyDecryptFailed\": \"Failed to decrypt transport session key\",\n \"crypto_transportBodyLimitInvalid\": \"Transport plaintext limit must be an integer between 1024 and 67108864 bytes\",\n \"crypto_transportBodyTooLarge\": \"Encrypted transport payload exceeds the configured byte limit\",\n \"crypto_transportTimeInvalid\": \"Your device and server clocks may be out of sync, or the request has expired. Enable automatic time synchronization and refresh to retry. If this continues, ask an administrator to check the server clock.\",\n \"crypto_transportBodyLimitConflict\": \"Explicit transport limit {limit} bytes is below the enabled module requirement of {required} bytes; adjust the module budget or explicit limit\",\n \"crypto_transportBusy\": \"Material processing is busy. Please retry shortly.\"\n}\n","{\n \"$schema\": \"https://inlang.com/schema/inlang-message-format\",\n \"crypto_notInitialized\": \"暗号モジュールが初期化されていません。先にcrypto.init()を呼び出してください\",\n \"crypto_initFailed\": \"暗号モジュールの初期化に失敗しました: {error}\",\n \"crypto_sm2PublicKeyInvalid\": \"SM2公開鍵の形式が無効です\",\n \"crypto_sm2PrivateKeyInvalid\": \"SM2秘密鍵の形式が無効です\",\n \"crypto_sm2EncryptEmpty\": \"SM2暗号化の結果が空です\",\n \"crypto_sm2DecryptFailed\": \"SM2復号に失敗したか、結果が無効です\",\n \"crypto_sm2SignEmpty\": \"SM2署名の結果が空です\",\n \"crypto_sm2KeyPairGenerateFailed\": \"SM2鍵ペアの生成に失敗しました: {error}\",\n \"crypto_sm2EncryptFailed\": \"SM2暗号化に失敗しました: {error}\",\n \"crypto_sm2DecryptFailedWithError\": \"SM2復号に失敗しました: {error}\",\n \"crypto_sm2SignFailed\": \"SM2署名に失敗しました: {error}\",\n \"crypto_sm2VerifyFailed\": \"SM2署名の検証に失敗しました: {error}\",\n \"crypto_sm3HashEmpty\": \"SM3ハッシュの結果が空です\",\n \"crypto_sm3HashFailed\": \"SM3ハッシュの計算に失敗しました: {error}\",\n \"crypto_sm3HmacFailed\": \"HMAC-SM3の計算に失敗しました: {error}\",\n \"crypto_sm3VerifyFailed\": \"SM3ハッシュの検証に失敗しました: {error}\",\n \"crypto_sm4KeyInvalid\": \"SM4鍵は16バイト(16進数32文字)である必要があります\",\n \"crypto_sm4CbcNeedIv\": \"CBCモードにはIVが必要です\",\n \"crypto_sm4IvInvalid\": \"SM4のIVは16バイト(16進数32文字)である必要があります\",\n \"crypto_sm4EncryptEmpty\": \"SM4暗号化の結果が空です\",\n \"crypto_sm4DecryptFailed\": \"SM4復号に失敗しました\",\n \"crypto_sm4EncryptFailed\": \"SM4暗号化に失敗しました: {error}\",\n \"crypto_sm4DecryptFailedWithError\": \"SM4復号に失敗しました: {error}\",\n \"crypto_passwordEmpty\": \"パスワードを空にすることはできません\",\n \"crypto_passwordHashEmpty\": \"パスワードとハッシュを空にすることはできません\",\n \"crypto_passwordHashFailed\": \"パスワードのハッシュ化に失敗しました\",\n \"crypto_hashFormatInvalid\": \"ハッシュの形式が無効です\",\n \"crypto_passwordVerifyFailed\": \"パスワードの検証に失敗しました\",\n \"crypto_transportClientKeyGenerateFailed\": \"通信クライアントの鍵ペアの生成に失敗しました\",\n \"crypto_transportServerKeyRingInvalid\": \"サーバーの転送鍵リングが不足または不正です。非公開の HAI_CRYPTO_TRANSPORT_SERVERKEYRING が完全で有効な JSON であることを確認し、全ノードに同じリングを配布してください。\",\n \"crypto_transportServerKeyUnknown\": \"トランスポートのサーバーキーバージョンが不明、または失効しています\",\n \"crypto_transportKeyStoreRequired\": \"トランスポート暗号化にはクライアント公開キーストアの明示的な指定が必要です\",\n \"crypto_transportKeyStoreTtlInvalid\": \"公開キーストアの TTL は1〜2147483647秒の整数で指定してください\",\n \"crypto_transportKeyStoreCapacityInvalid\": \"公開キーストアの容量は正の安全な整数で指定してください\",\n \"crypto_transportKeyStoreCapacityMismatch\": \"公開キーストアの共有容量設定が一致しません\",\n \"crypto_transportKeyStoreCapacityReached\": \"公開キーストアの容量上限に達しました\",\n \"crypto_transportKeyStoreOperationFailed\": \"公開キーストアの操作に失敗しました\",\n \"crypto_transportAuthenticationFailed\": \"トランスポート認証、リクエストとの紐付け、またはリプレイ検証に失敗しました\",\n \"crypto_transportKeyExchangeRequestFailed\": \"通信の鍵交換リクエストに失敗しました\",\n \"crypto_transportKeyExchangeHttpFailed\": \"通信の鍵交換でHTTP {status}が返されました\",\n \"crypto_transportKeyExchangeInvalidJson\": \"通信の鍵交換レスポンスが有効なJSONではありません\",\n \"crypto_transportKeyExchangeMissingFields\": \"通信の鍵交換レスポンスに必須フィールドがありません\",\n \"crypto_transportClientNotInitialized\": \"通信クライアントの鍵交換が完了していません\",\n \"crypto_transportClientNotRegistered\": \"通信クライアントが登録されていないか、有効期限が切れています\",\n \"crypto_transportRequestEncryptFailed\": \"通信リクエスト本文の暗号化に失敗しました\",\n \"crypto_transportRequestDecryptFailed\": \"通信リクエスト本文の復号に失敗しました\",\n \"crypto_transportResponseEncryptFailed\": \"通信レスポンス本文の暗号化に失敗しました\",\n \"crypto_transportResponseDecryptFailed\": \"通信レスポンス本文の復号に失敗しました\",\n \"crypto_transportSessionKeyEncryptFailed\": \"通信セッション鍵の暗号化に失敗しました\",\n \"crypto_transportSessionKeyDecryptFailed\": \"通信セッション鍵の復号に失敗しました\",\n \"crypto_transportBodyLimitInvalid\": \"通信平文の上限は 1024 から 67108864 バイトの整数で指定してください\",\n \"crypto_transportBodyTooLarge\": \"暗号化通信のデータが設定されたバイト上限を超えています\",\n \"crypto_transportTimeInvalid\": \"端末とサーバーの時刻が同期していないか、要求の有効期限が切れています。自動時刻同期を有効にしてページを再読み込みしてください。解消しない場合は管理者にサーバーの時刻確認を依頼してください。\",\n \"crypto_transportBodyLimitConflict\": \"明示された転送上限 {limit} バイトは有効なモジュールの必要量 {required} バイト未満です。予算または上限を変更してください\",\n \"crypto_transportBusy\": \"資料の処理が混み合っています。しばらくしてから再試行してください。\"\n}\n","{\n \"$schema\": \"https://inlang.com/schema/inlang-message-format\",\n \"crypto_notInitialized\": \"加密模块尚未初始化,请先调用 crypto.init()\",\n \"crypto_initFailed\": \"加密模块初始化失败:{error}\",\n \"crypto_sm2PublicKeyInvalid\": \"无效的 SM2 公钥格式\",\n \"crypto_sm2PrivateKeyInvalid\": \"无效的 SM2 私钥格式\",\n \"crypto_sm2EncryptEmpty\": \"SM2 加密返回空结果\",\n \"crypto_sm2DecryptFailed\": \"SM2 解密失败或返回无效结果\",\n \"crypto_sm2SignEmpty\": \"SM2 签名返回空结果\",\n \"crypto_sm2KeyPairGenerateFailed\": \"SM2 密钥对生成失败: {error}\",\n \"crypto_sm2EncryptFailed\": \"SM2 加密失败: {error}\",\n \"crypto_sm2DecryptFailedWithError\": \"SM2 解密失败: {error}\",\n \"crypto_sm2SignFailed\": \"SM2 签名失败: {error}\",\n \"crypto_sm2VerifyFailed\": \"SM2 验签失败: {error}\",\n \"crypto_sm3HashEmpty\": \"SM3 哈希返回空结果\",\n \"crypto_sm3HashFailed\": \"SM3 哈希计算失败: {error}\",\n \"crypto_sm3HmacFailed\": \"HMAC-SM3 计算失败: {error}\",\n \"crypto_sm3VerifyFailed\": \"SM3 哈希验证失败: {error}\",\n \"crypto_sm4KeyInvalid\": \"SM4 密钥必须为 16 字节(32 个十六进制字符)\",\n \"crypto_sm4CbcNeedIv\": \"CBC 模式必须提供 IV\",\n \"crypto_sm4IvInvalid\": \"SM4 IV 必须为 16 字节(32 个十六进制字符)\",\n \"crypto_sm4EncryptEmpty\": \"SM4 加密返回空结果\",\n \"crypto_sm4DecryptFailed\": \"SM4 解密失败\",\n \"crypto_sm4EncryptFailed\": \"SM4 加密失败: {error}\",\n \"crypto_sm4DecryptFailedWithError\": \"SM4 解密失败: {error}\",\n \"crypto_passwordEmpty\": \"密码不能为空\",\n \"crypto_passwordHashEmpty\": \"密码和哈希值不能为空\",\n \"crypto_passwordHashFailed\": \"密码哈希失败\",\n \"crypto_hashFormatInvalid\": \"无效的哈希格式\",\n \"crypto_passwordVerifyFailed\": \"密码验证失败\",\n \"crypto_transportClientKeyGenerateFailed\": \"传输加密客户端密钥生成失败\",\n \"crypto_transportServerKeyRingInvalid\": \"服务端传输密钥环缺失或无效。请检查私有环境变量 HAI_CRYPTO_TRANSPORT_SERVERKEYRING 是否为完整有效的 JSON,并向所有节点分发同一密钥环。\",\n \"crypto_transportServerKeyUnknown\": \"服务端传输密钥版本未知或已撤销\",\n \"crypto_transportKeyStoreRequired\": \"传输加密必须显式提供客户端公钥存储\",\n \"crypto_transportKeyStoreTtlInvalid\": \"公钥存储 TTL 必须为 1 到 2147483647 之间的整数秒\",\n \"crypto_transportKeyStoreCapacityInvalid\": \"公钥存储容量必须为正安全整数\",\n \"crypto_transportKeyStoreCapacityMismatch\": \"公钥存储的共享容量配置不一致\",\n \"crypto_transportKeyStoreCapacityReached\": \"公钥存储容量已满\",\n \"crypto_transportKeyStoreOperationFailed\": \"公钥存储操作失败\",\n \"crypto_transportAuthenticationFailed\": \"传输消息认证、请求绑定或防重放校验失败\",\n \"crypto_transportKeyExchangeRequestFailed\": \"传输加密密钥协商请求失败\",\n \"crypto_transportKeyExchangeHttpFailed\": \"传输加密密钥协商返回 HTTP {status}\",\n \"crypto_transportKeyExchangeInvalidJson\": \"传输加密密钥协商响应不是有效 JSON\",\n \"crypto_transportKeyExchangeMissingFields\": \"传输加密密钥协商响应缺少必要字段\",\n \"crypto_transportClientNotInitialized\": \"传输加密客户端尚未完成密钥协商\",\n \"crypto_transportClientNotRegistered\": \"传输加密客户端未注册或已过期\",\n \"crypto_transportRequestEncryptFailed\": \"传输加密请求体加密失败\",\n \"crypto_transportRequestDecryptFailed\": \"传输加密请求体解密失败\",\n \"crypto_transportResponseEncryptFailed\": \"传输加密响应体加密失败\",\n \"crypto_transportResponseDecryptFailed\": \"传输加密响应体解密失败\",\n \"crypto_transportSessionKeyEncryptFailed\": \"传输加密会话密钥加密失败\",\n \"crypto_transportSessionKeyDecryptFailed\": \"传输加密会话密钥解密失败\",\n \"crypto_transportBodyLimitInvalid\": \"传输明文容量必须是 1024 到 67108864 字节之间的整数\",\n \"crypto_transportBodyTooLarge\": \"加密传输报文超过配置的字节上限\",\n \"crypto_transportTimeInvalid\": \"设备与服务器时间可能不同步,或请求已过期。请开启自动校时并刷新重试;若仍失败,请联系管理员检查服务器时间。\",\n \"crypto_transportBodyLimitConflict\": \"显式传输上限 {limit} 字节小于已启用模块所需的 {required} 字节;请调整模块预算或显式上限\",\n \"crypto_transportBusy\": \"材料处理繁忙,请稍后重试\"\n}\n","/**\n * @h-ai/crypto — i18n\n *\n * 本文件提供加密模块的 i18n 文案访问入口。\n * @module crypto-i18n\n */\n\nimport { core } from '@h-ai/core'\nimport messagesEnUS from '../messages/en-US.json'\nimport messagesJaJP from '../messages/ja-JP.json'\nimport messagesZhCN from '../messages/zh-CN.json'\n\n/**\n * 模块内合法消息键,由中文词典推导;与英文词典一起维护。\n *\n * @example 模块内部上下文\n * ```ts\n * const key: CryptoMessageKey = 'crypto_sm2PublicKeyInvalid'\n * const message = cryptoM(key)\n * ```\n */\ntype CryptoMessageKey = keyof typeof messagesZhCN\n\n/**\n * 按 Core 当前 locale 获取加密模块消息;错误插值不能包含密钥或明文。\n * @param key - 已维护的消息键。\n * @param options - locale 覆盖与 params 插值选项。\n * @returns 本地化消息。\n *\n * @example 模块内部上下文\n * ```ts\n * const message = cryptoM('crypto_initFailed', { locale: 'en-US', params: { error: 'Initialization failed' } })\n * ```\n */\nexport const cryptoM = core.i18n.createMessageGetter<CryptoMessageKey>({\n 'zh-CN': messagesZhCN,\n 'en-US': messagesEnUS,\n 'ja-JP': messagesJaJP,\n})\n","/**\n * @h-ai/crypto — 公共类型\n *\n * 定义加密模块的对外接口类型。\n * @module crypto-types\n */\n\nimport type { ErrorInfo, HaiResult } from '@h-ai/core'\nimport type {\n TRANSPORT_PROTOCOL as TRANSPORT_PROTOCOL_T,\n TransportClient,\n TransportCreateServerOptions,\n TransportEncryptionManager,\n} from './transport/crypto-transport-types.js'\nimport { core } from '@h-ai/core'\n\nconst CryptoErrorInfo = {\n INVALID_INPUT: '002:400',\n INVALID_KEY: '003:400',\n NOT_INITIALIZED: '010:500',\n INIT_FAILED: '011:500',\n KEY_GENERATION_FAILED: '020:500',\n ENCRYPTION_FAILED: '021:500',\n DECRYPTION_FAILED: '022:500',\n SIGN_FAILED: '023:500',\n VERIFY_FAILED: '024:500',\n HASH_FAILED: '040:500',\n HMAC_FAILED: '041:500',\n INVALID_IV: '060:400',\n TRANSPORT_PAYLOAD_TOO_LARGE: '070:413',\n TRANSPORT_TIME_INVALID: '071:400',\n TRANSPORT_BUSY: '072:503',\n} as const satisfies ErrorInfo\n\n/**\n * 加密领域标准错误集合;先判断 HaiResult.success,错误上下文不得附带明文或私钥。\n *\n * @example\n * ```ts\n * import { crypto, HaiCryptoError } from '@h-ai/crypto'\n * const result = crypto.hash.hash('hello')\n * if (!result.success && result.error.code === HaiCryptoError.NOT_INITIALIZED.code) {\n * // 尚未初始化时按生命周期处理,不忽略错误继续加密。\n * const message = result.error.message\n * }\n * ```\n */\nexport const HaiCryptoError = core.error.buildHaiErrorsDef('crypto', CryptoErrorInfo)\n\n// ─── 非对称加密类型 ───\n\n/**\n * SM2 密文排列:1为C1C3C2默认值,0为显式C1C2C3;解密必须匹配加密排列。\n *\n * @example\n * ```ts\n * import { crypto, type CipherMode } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const generated = crypto.asymmetric.generateKeyPair()\n * if (!generated.success) throw new Error(generated.error.message)\n * const pair = generated.data\n * const mode: CipherMode = 1\n * const encrypted = crypto.asymmetric.encrypt('hello', pair.publicKey, { cipherMode: mode })\n * if (!encrypted.success) throw new Error(encrypted.error.message)\n * const decrypted = crypto.asymmetric.decrypt(encrypted.data, pair.privateKey, { cipherMode: mode })\n * if (!decrypted.success) throw new Error(decrypted.error.message)\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport type CipherMode = 0 | 1\n\n/**\n * SM2 公私钥对;私钥必须保密,不写日志、公开配置或响应。\n *\n * @example\n * ```ts\n * import { crypto, type KeyPair } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const generated = crypto.asymmetric.generateKeyPair()\n * if (!generated.success) throw new Error(generated.error.message)\n * const pair = generated.data\n * const keyPair: KeyPair = pair\n * const publicKey = keyPair.publicKey\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport interface KeyPair {\n /** 公钥(十六进制字符串,包含 04 前缀为非压缩格式) */\n publicKey: string\n /** 私钥(十六进制字符串,64 字符) */\n privateKey: string\n}\n\n/**\n * SM2 密文排列和输出编码;加解密 cipherMode 必须一致,解密可识别受支持的 base64 输出。\n *\n * @example\n * ```ts\n * import { crypto, type AsymmetricEncryptOptions } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const generated = crypto.asymmetric.generateKeyPair()\n * if (!generated.success) throw new Error(generated.error.message)\n * const pair = generated.data\n * const options: AsymmetricEncryptOptions = { cipherMode: 1, outputFormat: 'base64' }\n * const encrypted = crypto.asymmetric.encrypt('hello', pair.publicKey, options)\n * if (!encrypted.success) throw new Error(encrypted.error.message)\n * const decrypted = crypto.asymmetric.decrypt(encrypted.data, pair.privateKey, options)\n * if (!decrypted.success) throw new Error(decrypted.error.message)\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport interface AsymmetricEncryptOptions {\n /** 密文模式:0=C1C2C3(旧版),1=C1C3C2(国标,默认) */\n cipherMode?: CipherMode\n /** 输出格式 */\n outputFormat?: 'hex' | 'base64'\n}\n\n/**\n * SM2 签名的哈希与用户标识参数;验签必须使用相同设置,默认启用哈希。\n *\n * @example\n * ```ts\n * import { crypto, type SignOptions } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const generated = crypto.asymmetric.generateKeyPair()\n * if (!generated.success) throw new Error(generated.error.message)\n * const pair = generated.data\n * const options: SignOptions = { hash: true, userId: 'orders-service' }\n * const signature = crypto.asymmetric.sign('hello', pair.privateKey, options)\n * if (!signature.success) throw new Error(signature.error.message)\n * const verified = crypto.asymmetric.verify('hello', signature.data, pair.publicKey, options)\n * if (!verified.success) throw new Error(verified.error.message)\n * const accepted = verified.data\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport interface SignOptions {\n /** 是否对数据进行哈希(默认 true) */\n hash?: boolean\n /** 用户 ID(默认 \"1234567812345678\") */\n userId?: string\n}\n\n// ─── 哈希类型 ───\n\n/**\n * 字符串输入编码;hex 表示解码后的字节,Uint8Array 直接作为字节输入。\n *\n * @example\n * ```ts\n * import { crypto, type HashOptions } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const options: HashOptions = { inputEncoding: 'hex' }\n * const digest = crypto.hash.hash('6869', options)\n * if (!digest.success) throw new Error(digest.error.message)\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport interface HashOptions {\n /** 输入编码 */\n inputEncoding?: 'utf8' | 'hex'\n}\n\n// ─── 对称加密类型 ───\n\n/**\n * SM4 的 CBC/ECB 模式;新数据使用默认 CBC,ECB 会暴露相同明文块结构,两者都不提供 MAC。\n *\n * @example\n * ```ts\n * import { crypto, type SymmetricMode } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const mode: SymmetricMode = 'cbc'\n * const key = crypto.symmetric.generateKey()\n * const encrypted = crypto.symmetric.encrypt('hello', key, { mode })\n * if (!encrypted.success) throw new Error(encrypted.error.message)\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport type SymmetricMode = 'ecb' | 'cbc'\n\n/**\n * 结构化 SM4 ciphertext 的 hex/base64 编码标识,解密必须保留。\n *\n * @example\n * ```ts\n * import { crypto, type SymmetricCiphertextEncoding } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const outputFormat: SymmetricCiphertextEncoding = 'base64'\n * const key = crypto.symmetric.generateKey()\n * const encrypted = crypto.symmetric.encrypt('hello', key, { outputFormat })\n * if (!encrypted.success) throw new Error(encrypted.error.message)\n * const decrypted = crypto.symmetric.decrypt(encrypted.data, key)\n * if (!decrypted.success) throw new Error(decrypted.error.message)\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport type SymmetricCiphertextEncoding = 'hex' | 'base64'\n\n/**\n * SM4 模式、IV 与编码;CBC 未提供 IV 时随机生成,手动 IV 必须每次独立随机。\n *\n * @example\n * ```ts\n * import { crypto, type SymmetricEncryptOptions } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const options: SymmetricEncryptOptions = { mode: 'cbc', outputFormat: 'base64' }\n * const key = crypto.symmetric.generateKey()\n * const encrypted = crypto.symmetric.encrypt('hello', key, options)\n * if (!encrypted.success) throw new Error(encrypted.error.message)\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport interface SymmetricEncryptOptions {\n /** 加密模式;默认 cbc */\n mode?: SymmetricMode\n /** IV 向量(CBC 模式可选;未传时自动生成,32 个十六进制字符) */\n iv?: string\n /** 密文输出编码;默认 hex */\n outputFormat?: SymmetricCiphertextEncoding\n}\n\n/**\n * SM4 密文及 mode/encoding/可选 IV;保留全部字段才能正确解密,不含消息认证能力。\n *\n * @example\n * ```ts\n * import { crypto, type SymmetricEncryptedPayload } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const key = crypto.symmetric.generateKey()\n * const encrypted = crypto.symmetric.encrypt('hello', key)\n * if (!encrypted.success) throw new Error(encrypted.error.message)\n * const payload: SymmetricEncryptedPayload = encrypted.data\n * const decrypted = crypto.symmetric.decrypt(payload, key)\n * if (!decrypted.success) throw new Error(decrypted.error.message)\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport interface SymmetricEncryptedPayload {\n /** 加密模式 */\n readonly mode: SymmetricMode\n /** 密文内容,编码由 encoding 字段说明 */\n readonly ciphertext: string\n /** CBC 模式的 IV 向量;ECB 模式无该字段 */\n readonly iv?: string\n /** ciphertext 字段的编码 */\n readonly encoding: SymmetricCiphertextEncoding\n}\n\n/**\n * CBC 结构化密文,mode固定cbc且IV必填;仍需上层消息认证。\n *\n * @example\n * ```ts\n * import { crypto, type SymmetricCbcEncryptedPayload } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const key = crypto.symmetric.generateKey()\n * const encrypted = crypto.symmetric.encryptWithIV('hello', key)\n * if (!encrypted.success) throw new Error(encrypted.error.message)\n * const payload: SymmetricCbcEncryptedPayload = encrypted.data\n * const decrypted = crypto.symmetric.decrypt(payload, key)\n * if (!decrypted.success) throw new Error(decrypted.error.message)\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport interface SymmetricCbcEncryptedPayload extends SymmetricEncryptedPayload {\n readonly mode: 'cbc'\n readonly iv: string\n}\n\n/**\n * SM4 解密输入别名;传入加密返回的完整结构,不能用裸密文猜测IV或编码。\n *\n * @example\n * ```ts\n * import { crypto, type SymmetricDecryptInput } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const key = crypto.symmetric.generateKey()\n * const encrypted = crypto.symmetric.encrypt('hello', key)\n * if (!encrypted.success) throw new Error(encrypted.error.message)\n * const payload: SymmetricDecryptInput = encrypted.data\n * const decrypted = crypto.symmetric.decrypt(payload, key)\n * if (!decrypted.success) throw new Error(decrypted.error.message)\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport type SymmetricDecryptInput = SymmetricEncryptedPayload\n\n/**\n * encryptWithIV 的CBC结构化结果别名;含 mode、ciphertext、iv 与 encoding。\n *\n * @example\n * ```ts\n * import { crypto, type EncryptWithIVResult } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const key = crypto.symmetric.generateKey()\n * const encrypted = crypto.symmetric.encryptWithIV('hello', key)\n * if (!encrypted.success) throw new Error(encrypted.error.message)\n * const payload: EncryptWithIVResult = encrypted.data\n * const decrypted = crypto.symmetric.decrypt(payload, key)\n * if (!decrypted.success) throw new Error(decrypted.error.message)\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport type EncryptWithIVResult = SymmetricCbcEncryptedPayload\n\n// ─── 密码类型 ───\n\n/**\n * 迭代SM3密码参数;默认盐长16、迭代10000,合法范围以实现校验为准,已有哈希自行携带参数。\n *\n * @example\n * ```ts\n * import { crypto, type PasswordConfig } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const config: PasswordConfig = { saltLength: 16, iterations: 10000 }\n * const hashed = crypto.password.hash('test-password', config)\n * if (!hashed.success) throw new Error(hashed.error.message)\n * const verified = crypto.password.verify('test-password', hashed.data)\n * if (!verified.success) throw new Error(verified.error.message)\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport interface PasswordConfig {\n /** 盐值长度(默认 16) */\n saltLength?: number\n /** 迭代次数(默认 10000) */\n iterations?: number\n}\n\n// ─── 操作接口 ───\n\n/**\n * SM2 操作域;先初始化,所有 HaiResult 先检查 success,boolean 校验器按直接返回值使用。\n * 公钥曲线点有效不等于对端身份可信;可信公钥分发仍由TLS/受管信任链保证。\n *\n * @example\n * ```ts\n * import { crypto, type AsymmetricOperations } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const generated = crypto.asymmetric.generateKeyPair()\n * if (!generated.success) throw new Error(generated.error.message)\n * const pair = generated.data\n * const operations: AsymmetricOperations = crypto.asymmetric\n * const signature = operations.sign('hello', pair.privateKey)\n * if (!signature.success) throw new Error(signature.error.message)\n * const verified = operations.verify('hello', signature.data, pair.publicKey)\n * if (!verified.success) throw new Error(verified.error.message)\n * const matches = verified.data\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport interface AsymmetricOperations {\n /**\n * 生成密钥对\n *\n * @returns 成功时包含公私钥对;失败时返回 KEY_GENERATION_FAILED\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const generated = crypto.asymmetric.generateKeyPair()\n * if (!generated.success) throw new Error(generated.error.message)\n * const pair = generated.data\n * const publicKey = pair.publicKey\n * }\n * finally { await crypto.close() }\n * ```\n */\n generateKeyPair: () => HaiResult<KeyPair>\n /**\n * 非对称加密\n *\n * @param data - 待加密明文\n * @param publicKey - 公钥(十六进制,支持带/不带 04 前缀)\n * @param options - 加密选项(密文模式、输出格式)\n * @returns 成功时返回密文字符串;失败时返回 INVALID_KEY 或 ENCRYPTION_FAILED\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const generated = crypto.asymmetric.generateKeyPair()\n * if (!generated.success) throw new Error(generated.error.message)\n * const pair = generated.data\n * const encrypted = crypto.asymmetric.encrypt('hello', pair.publicKey, { cipherMode: 1, outputFormat: 'hex' })\n * if (!encrypted.success) throw new Error(encrypted.error.message)\n * }\n * finally { await crypto.close() }\n * ```\n */\n encrypt: (data: string, publicKey: string, options?: AsymmetricEncryptOptions) => HaiResult<string>\n /**\n * 非对称解密\n *\n * 自动检测 base64 格式输入并转换为 hex。\n *\n * @param ciphertext - 密文(hex 或 base64)\n * @param privateKey - 私钥(64 字符十六进制)\n * @param options - 解密选项(密文模式需与加密时一致)\n * @returns 成功时返回明文;失败时返回 INVALID_KEY 或 DECRYPTION_FAILED\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const generated = crypto.asymmetric.generateKeyPair()\n * if (!generated.success) throw new Error(generated.error.message)\n * const pair = generated.data\n * const encrypted = crypto.asymmetric.encrypt('hello', pair.publicKey)\n * if (!encrypted.success) throw new Error(encrypted.error.message)\n * const decrypted = crypto.asymmetric.decrypt(encrypted.data, pair.privateKey)\n * if (!decrypted.success) throw new Error(decrypted.error.message)\n * }\n * finally { await crypto.close() }\n * ```\n */\n decrypt: (ciphertext: string, privateKey: string, options?: AsymmetricEncryptOptions) => HaiResult<string>\n /**\n * 签名\n *\n * @param data - 待签名数据\n * @param privateKey - 私钥(64 字符十六进制)\n * @param options - 签名选项(hash 开关、userId)\n * @returns 成功时返回签名字符串;失败时返回 INVALID_KEY 或 SIGN_FAILED\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const generated = crypto.asymmetric.generateKeyPair()\n * if (!generated.success) throw new Error(generated.error.message)\n * const pair = generated.data\n * const signature = crypto.asymmetric.sign('hello', pair.privateKey)\n * if (!signature.success) throw new Error(signature.error.message)\n * }\n * finally { await crypto.close() }\n * ```\n */\n sign: (data: string, privateKey: string, options?: SignOptions) => HaiResult<string>\n /**\n * 验签\n *\n * @param data - 原始数据\n * @param signature - 签名(需与签名时使用相同的 hash/userId 选项)\n * @param publicKey - 公钥(支持带/不带 04 前缀)\n * @param options - 验签选项\n * @returns 成功时返回 boolean;失败时返回 INVALID_KEY 或 VERIFY_FAILED\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const generated = crypto.asymmetric.generateKeyPair()\n * if (!generated.success) throw new Error(generated.error.message)\n * const pair = generated.data\n * const signature = crypto.asymmetric.sign('hello', pair.privateKey)\n * if (!signature.success) throw new Error(signature.error.message)\n * const verified = crypto.asymmetric.verify('hello', signature.data, pair.publicKey)\n * if (!verified.success) throw new Error(verified.error.message)\n * const accepted = verified.data\n * }\n * finally { await crypto.close() }\n * ```\n */\n verify: (data: string, signature: string, publicKey: string, options?: SignOptions) => HaiResult<boolean>\n /**\n * 校验128/130字符SM2非压缩公钥编码及曲线点;有效不代表对端持有私钥。\n * @param key - 本次操作的密钥,不记录到日志。\n * @returns 直接boolean,false表示不匹配/未就绪。\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const generated = crypto.asymmetric.generateKeyPair()\n * if (!generated.success) throw new Error(generated.error.message)\n * const pair = generated.data\n * const valid = crypto.asymmetric.isValidPublicKey(pair.publicKey)\n * }\n * finally { await crypto.close() }\n * ```\n */\n isValidPublicKey: (key: string) => boolean\n /**\n * 校验64字符十六进制私钥格式;这是格式检查,不是密钥配对证明。\n * @param key - 本次操作的密钥,不记录到日志。\n * @returns 直接boolean,false表示不匹配/未就绪。\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const generated = crypto.asymmetric.generateKeyPair()\n * if (!generated.success) throw new Error(generated.error.message)\n * const pair = generated.data\n * const valid = crypto.asymmetric.isValidPrivateKey(pair.privateKey)\n * }\n * finally { await crypto.close() }\n * ```\n */\n isValidPrivateKey: (key: string) => boolean\n}\n\n/**\n * SM3 摘要、HMAC-SM3 与常量时间摘要匹配操作;摘要不是加密,HMAC密钥不能公开。\n *\n * @example\n * ```ts\n * import { crypto, type HashOperations } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const operations: HashOperations = crypto.hash\n * const digest = operations.hash('hello')\n * if (!digest.success) throw new Error(digest.error.message)\n * const verified = operations.verify('hello', digest.data)\n * if (!verified.success) throw new Error(verified.error.message)\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport interface HashOperations {\n /**\n * 计算哈希\n *\n * @param data - 待哈希数据(字符串或 Uint8Array)\n * @param options - 输入编码选项\n * @returns 成功时返回 64 字符十六进制哈希值;失败时返回 HASH_FAILED\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const digest = crypto.hash.hash('6869', { inputEncoding: 'hex' })\n * if (!digest.success) throw new Error(digest.error.message)\n * }\n * finally { await crypto.close() }\n * ```\n */\n hash: (data: string | Uint8Array, options?: HashOptions) => HaiResult<string>\n /**\n * 计算 HMAC\n *\n * 使用 HMAC 算法(RFC 2104)计算消息认证码。\n * 当密钥长度超过块大小(64 字节)时,会先对密钥进行哈希。\n *\n * @param data - 待计算数据\n * @param key - HMAC 密钥\n * @returns 成功时返回 64 字符十六进制 HMAC 值;失败时返回 HMAC_FAILED\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const key = crypto.symmetric.generateKey()\n * const tag = crypto.hash.hmac('hello', key)\n * if (!tag.success) throw new Error(tag.error.message)\n * }\n * finally { await crypto.close() }\n * ```\n */\n hmac: (data: string, key: string) => HaiResult<string>\n /**\n * 验证数据的哈希是否匹配\n *\n * 比较时忽略大小写。\n *\n * @param data - 原始数据\n * @param expectedHash - 期望的哈希值\n * @returns 成功时返回 boolean;失败时返回 HASH_FAILED\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const digest = crypto.hash.hash('hello')\n * if (!digest.success) throw new Error(digest.error.message)\n * const verified = crypto.hash.verify('hello', digest.data)\n * if (!verified.success) throw new Error(verified.error.message)\n * const matches = verified.data\n * }\n * finally { await crypto.close() }\n * ```\n */\n verify: (data: string, expectedHash: string) => HaiResult<boolean>\n}\n\n/**\n * SM4 同步操作域;默认CBC与随机IV,返回完整结构化密文;CBC原语不提供完整性认证。\n *\n * @example\n * ```ts\n * import { crypto, type SymmetricOperations } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const operations: SymmetricOperations = crypto.symmetric\n * const key = operations.generateKey()\n * const encrypted = operations.encrypt('hello', key)\n * if (!encrypted.success) throw new Error(encrypted.error.message)\n * const decrypted = operations.decrypt(encrypted.data, key)\n * if (!decrypted.success) throw new Error(decrypted.error.message)\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport interface SymmetricOperations {\n /**\n * 生成随机密钥(16 字节 = 32 个十六进制字符)\n * @returns 直接返回值,使用前先初始化模块。\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const key = crypto.symmetric.generateKey()\n * const valid = crypto.symmetric.isValidKey(key)\n * }\n * finally { await crypto.close() }\n * ```\n */\n generateKey: () => string\n /**\n * 生成随机 IV(16 字节 = 32 个十六进制字符)\n * @returns 直接返回值,使用前先初始化模块。\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const iv = crypto.symmetric.generateIV()\n * const valid = crypto.symmetric.isValidIV(iv)\n * }\n * finally { await crypto.close() }\n * ```\n */\n generateIV: () => string\n /**\n * 对称加密\n *\n * 默认 CBC + 自动随机 IV,返回 `{ mode, ciphertext, iv, encoding }`。\n * 显式 `{ mode: 'ecb' }` 可使用 ECB,但不推荐用于新数据。\n *\n * @param data - 待加密明文\n * @param key - 密钥(32 字符十六进制)\n * @param options - 加密模式/IV/输出格式\n * @returns 成功时返回结构化密文;失败时返回 INVALID_KEY/INVALID_IV/ENCRYPTION_FAILED\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const key = crypto.symmetric.generateKey()\n * const encrypted = crypto.symmetric.encrypt('hello', key)\n * if (!encrypted.success) throw new Error(encrypted.error.message)\n * }\n * finally { await crypto.close() }\n * ```\n */\n encrypt: (data: string, key: string, options?: SymmetricEncryptOptions) => HaiResult<SymmetricEncryptedPayload>\n /**\n * 对称解密\n *\n * 解密 `encrypt()` 返回的结构化密文;不猜测字符串格式。\n *\n * @param payload - 结构化密文(包含 mode/ciphertext/iv/encoding)\n * @param key - 密钥(32 字符十六进制)\n * @returns 成功时返回明文;失败时返回 INVALID_KEY/INVALID_IV/DECRYPTION_FAILED\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const key = crypto.symmetric.generateKey()\n * const encrypted = crypto.symmetric.encrypt('hello', key)\n * if (!encrypted.success) throw new Error(encrypted.error.message)\n * const decrypted = crypto.symmetric.decrypt(encrypted.data, key)\n * if (!decrypted.success) throw new Error(decrypted.error.message)\n * }\n * finally { await crypto.close() }\n * ```\n */\n decrypt: (payload: SymmetricDecryptInput, key: string) => HaiResult<string>\n /**\n * 带 IV 加密(CBC 模式,自动生成随机 IV)\n *\n * @param data - 待加密明文\n * @param key - 密钥(32 字符十六进制)\n * @returns 成功时返回完整 { mode, ciphertext, iv, encoding };失败时同 encrypt\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const key = crypto.symmetric.generateKey()\n * const encrypted = crypto.symmetric.encryptWithIV('hello', key)\n * if (!encrypted.success) throw new Error(encrypted.error.message)\n * }\n * finally { await crypto.close() }\n * ```\n */\n encryptWithIV: (data: string, key: string) => HaiResult<EncryptWithIVResult>\n /**\n * 带 IV 解密(CBC 模式)\n *\n * 不提供完整性认证。传输场景必须用 transport 先验签和验证 MAC,禁止直接对 HTTP 密文调用此 primitive。\n *\n * @param ciphertext - 密文\n * @param key - 密钥\n * @param iv - 加密时使用的 IV\n * @returns 成功时返回明文;失败时同 decrypt\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const key = crypto.symmetric.generateKey()\n * const encrypted = crypto.symmetric.encryptWithIV('hello', key)\n * if (!encrypted.success) throw new Error(encrypted.error.message)\n * const decrypted = crypto.symmetric.decryptWithIV(encrypted.data.ciphertext, key, encrypted.data.iv)\n * if (!decrypted.success) throw new Error(decrypted.error.message)\n * }\n * finally { await crypto.close() }\n * ```\n */\n decryptWithIV: (ciphertext: string, key: string, iv: string) => HaiResult<string>\n /**\n * 校验密钥格式是否合法(32 字符十六进制)\n * @param key - 本次操作的密钥,不记录到日志。\n * @returns 直接boolean,false表示不匹配/未就绪。\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const key = crypto.symmetric.generateKey()\n * const valid = crypto.symmetric.isValidKey(key)\n * }\n * finally { await crypto.close() }\n * ```\n */\n isValidKey: (key: string) => boolean\n /**\n * 校验 IV 格式是否合法(32 字符十六进制)\n * @param iv - 实际调用输入,按该方法约束验证。\n * @returns 直接boolean,false表示不匹配/未就绪。\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const iv = crypto.symmetric.generateIV()\n * const valid = crypto.symmetric.isValidIV(iv)\n * }\n * finally { await crypto.close() }\n * ```\n */\n isValidIV: (iv: string) => boolean\n}\n\n/**\n * 迭代加盐SM3密码存储操作;验证从 $hai$ 格式读取参数,返回成功false表示密码不匹配。\n *\n * @example\n * ```ts\n * import { crypto, type PasswordOperations } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const operations: PasswordOperations = crypto.password\n * const hashed = operations.hash('test-password')\n * if (!hashed.success) throw new Error(hashed.error.message)\n * const verified = operations.verify('test-password', hashed.data)\n * if (!verified.success) throw new Error(verified.error.message)\n * const matches = verified.data\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport interface PasswordOperations {\n /**\n * 对密码进行哈希\n *\n * 输出格式: `$hai$<iterations>$<salt>$<hash>`\n *\n * @param password - 明文密码(不能为空)\n * @param config - 可选配置(盐值长度、迭代次数)\n * @returns 成功时返回格式化的哈希字符串;失败时返回 INVALID_INPUT 或 HASH_FAILED\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const hashed = crypto.password.hash('test-password', { iterations: 10000, saltLength: 16 })\n * if (!hashed.success) throw new Error(hashed.error.message)\n * }\n * finally { await crypto.close() }\n * ```\n */\n hash: (password: string, config?: PasswordConfig) => HaiResult<string>\n /**\n * 验证密码是否匹配\n *\n * 自动从哈希字符串中解析迭代次数和盐值进行重新计算。\n *\n * @param password - 待验证的明文密码\n * @param hash - 存储的哈希值(格式: `$hai$<iterations>$<salt>$<hash>`)\n * @returns 成功时返回 boolean;失败时返回 INVALID_INPUT 或 VERIFY_FAILED\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const hashed = crypto.password.hash('test-password')\n * if (!hashed.success) throw new Error(hashed.error.message)\n * const verified = crypto.password.verify('test-password', hashed.data)\n * if (!verified.success) throw new Error(verified.error.message)\n * const matches = verified.data\n * }\n * finally { await crypto.close() }\n * ```\n */\n verify: (password: string, hash: string) => HaiResult<boolean>\n}\n\n// ─── 传输加密 ───\n\n/**\n * 认证传输工厂;需先初始化crypto,服务端显式受管密钥环+共享registry,客户端通过TLS协商公钥。\n * 协议v2绑定方向、HTTP方法/路径/状态、密钥版本和nonce,验签/MAC成功后才解密;防重放不替代业务幂等。\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const client = crypto.transport.createClient({ keyExchangeUrl: 'https://api.example.com/api/v1/_hai/key-exchange' })\n * try {\n * const ready = await client.init()\n * if (!ready.success) throw new Error(ready.error.message)\n * const response = await client.encryptedFetch('https://api.example.com/api/v1/orders')\n * if (!response.ok) throw new Error('HTTP request failed')\n * }\n * finally { client.destroy() }\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport interface TransportOperations {\n /**\n * 创建服务端传输加密管理器。\n *\n * serverKeyRing/keyStore 均必填;生产使用相同受管密钥环与共享 registry。\n * 成功返回 manager;缺失、格式错误或公私钥错配返回脱敏 HaiResult 错误。\n *\n * @remarks\n * 通常在服务启动阶段创建一次,并交给 HTTP 中间件 / 路由处理器复用。\n * @param options - 实际调用输入,按该方法约束验证。\n * @returns HaiResult,先检查success再读取data。\n *\n * @example\n * ```ts\n * import { crypto, createRedisTransportKeyStore, parseTransportServerKeyRing } from '@h-ai/crypto'\n * import { cache } from '@h-ai/cache'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const connected = await cache.init({ type: 'redis', host: 'cache', port: 6379, password: process.env.HAI_CACHE_PASSWORD })\n * if (!connected.success) throw new Error(connected.error.message)\n * try {\n * const registry = createRedisTransportKeyStore({ cache, ttlSeconds: 3600 })\n * const ring = parseTransportServerKeyRing(process.env.HAI_CRYPTO_TRANSPORT_SERVERKEYRING)\n * if (!ring.success) throw new Error(ring.error.message)\n * const created = crypto.transport.createServer({ serverKeyRing: ring.data, keyStore: registry })\n * if (!created.success) throw new Error(created.error.message)\n * const manager = created.data\n * try {\n * const currentVersion = manager.getServerKeyId()\n * const publicKey = manager.getServerPublicKey()\n * }\n * finally { await manager.close() }\n * }\n * finally { await cache.close() }\n * }\n * finally { await crypto.close() }\n * ```\n */\n createServer: (options: TransportCreateServerOptions) => HaiResult<TransportEncryptionManager>\n /**\n * 创建客户端传输加密会话。\n *\n * options.keyExchangeUrl:密钥协商端点完整 URL。\n * options.fetch:实际发送 HTTP 请求的 fetch(默认 `globalThis.fetch`)。\n *\n * @remarks\n * 返回的是“单会话”客户端:同一个实例会复用已协商得到的 `clientId` 与服务端公钥;\n * 调用 `destroy()` 后会回到未协商状态。\n * @param options - 实际调用输入,按该方法约束验证。\n * @param options.keyExchangeUrl - 密钥协商端点完整 URL。\n * @param options.fetch - 实际发送 HTTP 请求的 fetch,默认 `globalThis.fetch`。\n * @param options.maxPlaintextBytes - 可选本地明文 UTF-8 字节上限,默认跟随服务端。\n * @returns 直接返回值,使用前先初始化模块。\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const client = crypto.transport.createClient({ keyExchangeUrl: 'https://api.example.com/api/v1/_hai/key-exchange' })\n * try {\n * const ready = await client.init()\n * if (!ready.success) throw new Error(ready.error.message)\n * const response = await client.encryptedFetch('https://api.example.com/api/v1/orders')\n * if (!response.ok) throw new Error('HTTP request failed')\n * }\n * finally { client.destroy() }\n * }\n * finally { await crypto.close() }\n * ```\n */\n createClient: (options: { keyExchangeUrl: string, fetch?: typeof fetch, maxPlaintextBytes?: number }) => TransportClient\n /** 协议常量(headers、密钥协商默认路径)。 */\n readonly protocol: typeof TRANSPORT_PROTOCOL_T\n}\n\n// ─── 函数接口 ───\n\n/**\n * 加密模块服务接口;init检查HaiResult,close返回void,调用不能把原语当作已认证HTTP协议。\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const digest = crypto.hash.hash('hello')\n * if (!digest.success) throw new Error(digest.error.message)\n * const value = digest.data\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport interface CryptoFunctions {\n /**\n * 初始化加密模块\n *\n * 创建非对称/哈希/对称/密码哈希操作实例。\n * 重复调用会先关闭再重新初始化。\n *\n * @returns 成功时返回 ok(undefined);失败时返回 INIT_FAILED\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * await crypto.close()\n * ```\n */\n init: () => Promise<HaiResult<void>>\n /**\n * 关闭加密模块,释放内部状态\n *\n * 关闭后再访问 asymmetric/hash/symmetric/password 会返回 NOT_INITIALIZED 错误。\n * @returns 异步操作结果;存储或网络故障按方法契约拒绝。\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * await crypto.close()\n * const ready = crypto.isInitialized\n * ```\n */\n close: () => Promise<void>\n /** 是否已初始化 */\n readonly isInitialized: boolean\n /** 非对称加密操作(未初始化时所有方法返回 NOT_INITIALIZED) */\n readonly asymmetric: AsymmetricOperations\n /** 哈希操作(未初始化时所有方法返回 NOT_INITIALIZED) */\n readonly hash: HashOperations\n /** 对称加密操作(未初始化时所有方法返回 NOT_INITIALIZED) */\n readonly symmetric: SymmetricOperations\n /** 密码哈希操作(未初始化时所有方法返回 NOT_INITIALIZED) */\n readonly password: PasswordOperations\n /** 传输加密操作(端到端混合加密;createServer 在未初始化时返回 NOT_INITIALIZED) */\n readonly transport: TransportOperations\n}\n","/**\n * @h-ai/crypto — 密码操作\n *\n * 提供迭代加盐(SM3)密码哈希与校验功能。\n * @module crypto-password\n */\n\nimport type { HaiResult } from '@h-ai/core'\n\nimport type { HashOperations, PasswordConfig, PasswordOperations } from './crypto-types.js'\nimport { core, err, ok } from '@h-ai/core'\n\nimport { cryptoM } from './crypto-i18n.js'\nimport { HaiCryptoError } from './crypto-types.js'\n\n// ─── 常量 ───\n\n/** 迭代次数最小值(防止退化为 0 迭代导致明文等价泄漏) */\nconst MIN_ITERATIONS = 1\n/** 迭代次数最大值(防止伪造哈希触发 CPU 饱和) */\nconst MAX_ITERATIONS = 1_000_000\n/** 盐值长度范围,限制异常输入 */\nconst MIN_SALT_LENGTH = 8\nconst MAX_SALT_LENGTH = 128\n\n// ─── 依赖接口 ───\n\n/**\n * 内部密码工厂依赖;复用实际 HashOperations,不替换为另一个摘要协议。\n *\n * @example 模块内部上下文\n * ```ts\n * const { crypto } = await import('@h-ai/crypto')\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const deps: PasswordDeps = { hash: crypto.hash }\n * const operations = createPasswordFunctions(deps)\n * const hashed = operations.hash('test-password', { iterations: 10000, saltLength: 16 })\n * if (!hashed.success) throw new Error(hashed.error.message)\n * }\n * finally { await crypto.close() }\n * ```\n */\ninterface PasswordDeps {\n /** 哈希操作实例,用于迭代哈希计算 */\n hash: HashOperations\n}\n\n// ─── 工具函数 ───\n\n/**\n * 用Web Crypto随机字节生成当前密码格式的字母数字盐;本函数按字节取模映射,不承诺字符分布完全均匀。\n * @param length - 已由密码配置校验的盐字符数。\n * @returns 新盐文本,不与不同密码记录共用。\n *\n * @example 模块内部上下文\n * ```ts\n * const salt = generateSalt(16)\n * ```\n */\nfunction generateSalt(length: number): string {\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'\n const randomBytes = new Uint8Array(length)\n globalThis.crypto.getRandomValues(randomBytes)\n let salt = ''\n for (let i = 0; i < length; i++) {\n salt += chars.charAt(randomBytes[i] % chars.length)\n }\n return salt\n}\n\n/**\n * 迭代SM3进行当前密码格式的密钥拉伸;任一轮失败立即返回,不继续使用失败结果。\n * @param hash - 实际HashOperations。\n * @param data - 密码输入。\n * @param salt - 当前记录的独立盐。\n * @param iterations - 已校验的正整数轮数。\n * @returns 最终SM3或原失败HaiResult。\n *\n * @example 模块内部上下文\n * ```ts\n * const { crypto } = await import('@h-ai/crypto')\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const result = iterateHash(crypto.hash, 'test-password', generateSalt(16), 10000)\n * if (!result.success) throw new Error(result.error.message)\n * }\n * finally { await crypto.close() }\n * ```\n */\nfunction iterateHash(\n hash: HashOperations,\n data: string,\n salt: string,\n iterations: number,\n): HaiResult<string> {\n let current = salt + data\n for (let i = 0; i < iterations; i++) {\n const result = hash.hash(current)\n if (!result.success) {\n return result\n }\n current = result.data\n }\n return ok(current)\n}\n\n// ─── 密码操作工厂 ───\n\n/**\n * 创建模块内部迭代 SM3 加盐密码操作,格式为 $hai$iterations$salt$hash;包用户使用 crypto.password。\n * @param deps - 实际哈希操作。\n * @returns 密码哈希/校验操作,业务失败返回 HaiResult。\n *\n * @example 模块内部上下文\n * ```ts\n * const { crypto } = await import('@h-ai/crypto')\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const password = createPasswordFunctions({ hash: crypto.hash })\n * const hashed = password.hash('test-password')\n * if (!hashed.success) throw new Error(hashed.error.message)\n * const verified = password.verify('test-password', hashed.data)\n * if (!verified.success) throw new Error(verified.error.message)\n * const matches = verified.data\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport function createPasswordFunctions(deps: PasswordDeps): PasswordOperations {\n const { hash: hashOps } = deps\n\n return {\n /**\n * 对密码进行迭代加盐哈希\n *\n * 输出格式: `$hai$<iterations>$<salt>$<hash>`\n *\n * @param password - 明文密码(不能为空)\n * @param config - 可选配置(盐值长度、迭代次数)\n * @returns 成功时返回格式化的哈希字符串;失败时返回 INVALID_INPUT 或 HASH_FAILED\n */\n hash(password: string, config: PasswordConfig = {}): HaiResult<string> {\n const { saltLength = 16, iterations = 10000 } = config\n\n try {\n if (!password) {\n return err(\n HaiCryptoError.INVALID_INPUT,\n cryptoM('crypto_passwordEmpty'),\n )\n }\n\n if (!Number.isInteger(iterations) || iterations < MIN_ITERATIONS || iterations > MAX_ITERATIONS) {\n return err(\n HaiCryptoError.INVALID_INPUT,\n cryptoM('crypto_hashFormatInvalid'),\n )\n }\n if (!Number.isInteger(saltLength) || saltLength < MIN_SALT_LENGTH || saltLength > MAX_SALT_LENGTH) {\n return err(\n HaiCryptoError.INVALID_INPUT,\n cryptoM('crypto_hashFormatInvalid'),\n )\n }\n\n const salt = generateSalt(saltLength)\n const hashResult = iterateHash(hashOps, password, salt, iterations)\n if (!hashResult.success) {\n return hashResult\n }\n\n const formatted = `$hai$${iterations}$${salt}$${hashResult.data}`\n return ok(formatted)\n }\n catch (error) {\n return err(\n HaiCryptoError.HASH_FAILED,\n cryptoM('crypto_passwordHashFailed'),\n error,\n )\n }\n },\n\n /**\n * 验证密码是否匹配已存储的哈希\n *\n * 从哈希字符串中解析迭代次数和盐值,重新计算后比较。\n * 格式要求: `$hai$<iterations>$<salt>$<hash>`\n *\n * @param password - 待验证的明文密码\n * @param hash - 存储的哈希值\n * @returns 成功时返回 boolean;失败时返回 INVALID_INPUT 或 VERIFY_FAILED\n */\n verify(password: string, hash: string): HaiResult<boolean> {\n try {\n if (!password || !hash) {\n return err(\n HaiCryptoError.INVALID_INPUT,\n cryptoM('crypto_passwordHashEmpty'),\n )\n }\n\n const parts = hash.split('$')\n if (parts.length !== 5 || parts[1] !== 'hai') {\n return err(\n HaiCryptoError.INVALID_INPUT,\n cryptoM('crypto_hashFormatInvalid'),\n )\n }\n\n const storedIterations = Number.parseInt(parts[2], 10)\n const salt = parts[3]\n const storedHash = parts[4]\n\n if (\n Number.isNaN(storedIterations)\n || storedIterations < MIN_ITERATIONS\n || storedIterations > MAX_ITERATIONS\n || !salt\n || !storedHash\n ) {\n return err(\n HaiCryptoError.INVALID_INPUT,\n cryptoM('crypto_hashFormatInvalid'),\n )\n }\n\n const hashResult = iterateHash(hashOps, password, salt, storedIterations)\n if (!hashResult.success) {\n return hashResult\n }\n\n return ok(core.string.constantTimeEqual(hashResult.data, storedHash))\n }\n catch (error) {\n return err(\n HaiCryptoError.VERIFY_FAILED,\n cryptoM('crypto_passwordVerifyFailed'),\n error,\n )\n }\n },\n }\n}\n","/**\n * @h-ai/crypto — SM2 公钥输入校验。\n * @module crypto-public-key\n */\n\n// @ts-expect-error sm-crypto 未提供类型声明。\nimport smCrypto from 'sm-crypto'\n\nconst SM2_PUBLIC_KEY_REGEX = /^(?:04)?[0-9a-f]{128}$/i\n\n/**\n * 纯函数校验 SM2 公钥的编码及曲线点,不初始化模块或访问 registry。\n * 仅接受128字符无前缀或130字符04前缀的十六进制非压缩点;拒绝曲线外点及其它编码。\n * @param publicKey - 不可信的输入。\n * @returns 有效字符串时为 true,并收窄类型;不证明密钥所有权,注册后仍须验签。\n *\n * @example\n * ```ts\n * import { crypto, isValidSM2PublicKey } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const generated = crypto.asymmetric.generateKeyPair()\n * if (!generated.success) throw new Error(generated.error.message)\n * const pair = generated.data\n * const valid = isValidSM2PublicKey(pair.publicKey)\n * const invalid = isValidSM2PublicKey('not-a-public-key')\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport function isValidSM2PublicKey(publicKey: unknown): publicKey is string {\n if (typeof publicKey !== 'string' || (publicKey.length !== 128 && publicKey.length !== 130) || !SM2_PUBLIC_KEY_REGEX.test(publicKey))\n return false\n const encoded = publicKey.length === 128 ? `04${publicKey}` : publicKey\n return smCrypto.sm2.verifyPublicKey(encoded) === true\n}\n","/**\n * @h-ai/crypto — 内部工具函数\n *\n * 提供 SM2/SM4 共用的编码转换辅助函数。 仅供模块内部使用,不对外导出。\n * @module crypto-utils\n */\n\n/**\n * 内部编码启发式:仅检测+、/或末尾=,不是严格Base64验证器。\n * @param str - 原始密文文本。\n * @returns 是否走Base64解码分支;不能据此认可不可信输入。\n *\n * @example 模块内部上下文\n * ```ts\n * const likelyBase64 = isBase64('aGk=')\n * const likelyHex = isBase64('6869')\n * ```\n */\nexport function isBase64(str: string): boolean {\n return str.includes('+') || str.includes('/') || str.endsWith('=')\n}\n\n/**\n * 内部Hex转Base64工具;调用前保证有效且偶数长度Hex,本函数不校验编码。\n * @param hex - 已校验Hex字节文本。\n * @returns Base64编码;大输入须在上层先限制预算。\n *\n * @example 模块内部上下文\n * ```ts\n * const encoded = hexToBase64('6869')\n * const decoded = base64ToHex(encoded)\n * ```\n */\nexport function hexToBase64(hex: string): string {\n const bytes = new Uint8Array(hex.length / 2)\n for (let i = 0; i < hex.length; i += 2) {\n bytes[i / 2] = Number.parseInt(hex.slice(i, i + 2), 16)\n }\n return btoa(String.fromCharCode(...bytes))\n}\n\n/**\n * 内部Base64转小写Hex;非法输入由atob抛错,最近业务边界负责转换HaiResult。\n * @param base64 - 编码后的字节文本。\n * @returns 小写Hex字符串。\n * @throws TypeError或宿主atob解码异常。\n *\n * @example 模块内部上下文\n * ```ts\n * const decoded = base64ToHex('aGk=')\n * const encoded = hexToBase64(decoded)\n * ```\n */\nexport function base64ToHex(base64: string): string {\n const binary = atob(base64)\n const bytes = new Uint8Array(binary.length)\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i)\n }\n return Array.from(bytes)\n .map(b => b.toString(16).padStart(2, '0'))\n .join('')\n}\n","/**\n * @h-ai/crypto — SM2 非对称加密\n *\n * 提供 SM2 密钥对生成、加解密、签名与验签操作。\n * @module crypto-sm2\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { AsymmetricEncryptOptions, AsymmetricOperations, KeyPair, SignOptions } from './crypto-types.js'\n\nimport { err, ok } from '@h-ai/core'\n// @ts-expect-error sm-crypto 无类型定义\nimport smCrypto from 'sm-crypto'\n\nimport { cryptoM } from './crypto-i18n.js'\nimport { isValidSM2PublicKey } from './crypto-public-key.js'\nimport {\n\n HaiCryptoError,\n\n} from './crypto-types.js'\nimport { base64ToHex, hexToBase64, isBase64 } from './crypto-utils.js'\n\nconst { sm2 } = smCrypto\nconst SM2_PRIVATE_KEY_REGEX = /^[0-9a-f]{64}$/i\n\n// ─── SM2 算法实现 ───\n\n/**\n * 创建模块内部 SM2 原语;支持匹配的密文模式与 hex/base64 编码,公钥验证实际曲线点。\n * 包用户通过初始化后的 crypto.asymmetric 访问。\n * @returns 非对称操作;加密与签名使用不同方法,不能用加密代替发送方认证。\n *\n * @example 模块内部上下文\n * ```ts\n * const asymmetric = createSM2()\n * const generated = asymmetric.generateKeyPair()\n * if (!generated.success) throw new Error(generated.error.message)\n * const encrypted = asymmetric.encrypt('hello', generated.data.publicKey)\n * if (!encrypted.success) throw new Error(encrypted.error.message)\n * const decrypted = asymmetric.decrypt(encrypted.data, generated.data.privateKey)\n * if (!decrypted.success) throw new Error(decrypted.error.message)\n * ```\n */\nexport function createSM2(): AsymmetricOperations {\n return {\n /**\n * 生成 SM2 密钥对\n *\n * @returns 成功时返回包含公钥(130 字符含 04 前缀)和私钥(64 字符)的密钥对\n */\n generateKeyPair(): HaiResult<KeyPair> {\n try {\n const keyPair = sm2.generateKeyPairHex()\n return ok({\n publicKey: keyPair.publicKey,\n privateKey: keyPair.privateKey,\n })\n }\n catch (error) {\n return err(\n HaiCryptoError.KEY_GENERATION_FAILED,\n cryptoM('crypto_sm2KeyPairGenerateFailed', { params: { error: error instanceof Error ? error.message : String(error) } }),\n error,\n )\n }\n },\n\n /**\n * SM2 非对称加密\n *\n * 公钥自动补齐 04 前缀;支持 hex/base64 输出。\n *\n * @param data - 待加密明文\n * @param publicKey - 公钥(支持带/不带 04 前缀)\n * @param options - 加密选项(密文模式、输出格式)\n * @returns 成功时返回密文;失败时返回 INVALID_KEY 或 ENCRYPTION_FAILED\n */\n encrypt(\n data: string,\n publicKey: string,\n options: AsymmetricEncryptOptions = {},\n ): HaiResult<string> {\n const { cipherMode = 1, outputFormat = 'hex' } = options\n\n if (!this.isValidPublicKey(publicKey)) {\n return err(\n HaiCryptoError.INVALID_KEY,\n cryptoM('crypto_sm2PublicKeyInvalid'),\n )\n }\n\n try {\n // 确保公钥带 04 前缀\n const key = publicKey.length === 130 ? publicKey : `04${publicKey}`\n const encrypted = sm2.doEncrypt(data, key, cipherMode)\n\n if (!encrypted) {\n return err(\n HaiCryptoError.ENCRYPTION_FAILED,\n cryptoM('crypto_sm2EncryptEmpty'),\n )\n }\n\n if (outputFormat === 'base64') {\n return ok(hexToBase64(encrypted))\n }\n\n return ok(encrypted)\n }\n catch (error) {\n return err(\n HaiCryptoError.ENCRYPTION_FAILED,\n cryptoM('crypto_sm2EncryptFailed', { params: { error: error instanceof Error ? error.message : String(error) } }),\n error,\n )\n }\n },\n\n /**\n * SM2 非对称解密\n *\n * 自动检测 base64 格式输入并转换为 hex 后解密。\n *\n * @param ciphertext - 密文(hex 或 base64)\n * @param privateKey - 私钥(64 字符十六进制)\n * @param options - 解密选项(密文模式需与加密时一致)\n * @returns 成功时返回明文;失败时返回 INVALID_KEY 或 DECRYPTION_FAILED\n */\n decrypt(\n ciphertext: string,\n privateKey: string,\n options: AsymmetricEncryptOptions = {},\n ): HaiResult<string> {\n const { cipherMode = 1 } = options\n\n if (!this.isValidPrivateKey(privateKey)) {\n return err(\n HaiCryptoError.INVALID_KEY,\n cryptoM('crypto_sm2PrivateKeyInvalid'),\n )\n }\n\n try {\n // 自动检测并转换 base64 格式\n let input = ciphertext\n if (isBase64(ciphertext)) {\n input = base64ToHex(ciphertext)\n }\n\n const decrypted = sm2.doDecrypt(input, privateKey, cipherMode)\n\n if (decrypted === false || decrypted === null || decrypted === undefined) {\n return err(\n HaiCryptoError.DECRYPTION_FAILED,\n cryptoM('crypto_sm2DecryptFailed'),\n )\n }\n\n return ok(decrypted)\n }\n catch (error) {\n return err(\n HaiCryptoError.DECRYPTION_FAILED,\n cryptoM('crypto_sm2DecryptFailedWithError', { params: { error: error instanceof Error ? error.message : String(error) } }),\n error,\n )\n }\n },\n\n /**\n * SM2 数字签名\n *\n * 默认对数据先做哈希(hash=true),使用 userId 作为签名附加参数。\n *\n * @param data - 待签名数据\n * @param privateKey - 私钥(64 字符十六进制)\n * @param options - 签名选项(hash 开关、userId)\n * @returns 成功时返回签名字符串;失败时返回 INVALID_KEY 或 SIGN_FAILED\n */\n sign(\n data: string,\n privateKey: string,\n options: SignOptions = {},\n ): HaiResult<string> {\n const { hash = true, userId = '1234567812345678' } = options\n\n if (!this.isValidPrivateKey(privateKey)) {\n return err(\n HaiCryptoError.INVALID_KEY,\n cryptoM('crypto_sm2PrivateKeyInvalid'),\n )\n }\n\n try {\n const signature = sm2.doSignature(data, privateKey, { hash, userId })\n\n if (!signature) {\n return err(\n HaiCryptoError.SIGN_FAILED,\n cryptoM('crypto_sm2SignEmpty'),\n )\n }\n\n return ok(signature)\n }\n catch (error) {\n return err(\n HaiCryptoError.SIGN_FAILED,\n cryptoM('crypto_sm2SignFailed', { params: { error: error instanceof Error ? error.message : String(error) } }),\n error,\n )\n }\n },\n\n /**\n * SM2 签名验证\n *\n * 公钥自动补齐 04 前缀;hash/userId 需与签名时一致。\n *\n * @param data - 原始数据\n * @param signature - 签名值\n * @param publicKey - 公钥(支持带/不带 04 前缀)\n * @param options - 验签选项(hash 开关、userId)\n * @returns 成功时返回 boolean;失败时返回 INVALID_KEY 或 VERIFY_FAILED\n */\n verify(\n data: string,\n signature: string,\n publicKey: string,\n options: SignOptions = {},\n ): HaiResult<boolean> {\n const { hash = true, userId = '1234567812345678' } = options\n\n if (!this.isValidPublicKey(publicKey)) {\n return err(\n HaiCryptoError.INVALID_KEY,\n cryptoM('crypto_sm2PublicKeyInvalid'),\n )\n }\n\n try {\n // 确保公钥带 04 前缀\n const key = publicKey.length === 130 ? publicKey : `04${publicKey}`\n const isValid = sm2.doVerifySignature(data, signature, key, { hash, userId })\n return ok(!!isValid)\n }\n catch (error) {\n return err(\n HaiCryptoError.VERIFY_FAILED,\n cryptoM('crypto_sm2VerifyFailed', { params: { error: error instanceof Error ? error.message : String(error) } }),\n error,\n )\n }\n },\n\n /**\n * 校验公钥编码及曲线点是否合法\n *\n * 合法格式:128 字符十六进制(无前缀)或 130 字符(含 04 前缀)。\n *\n * @param key - 待校验公钥\n * @returns 编码有效且为 SM2 曲线上的非无穷远点时返回 true\n * @example `crypto.asymmetric.isValidPublicKey(clientPublicKey)`\n */\n isValidPublicKey(key: string): boolean {\n return isValidSM2PublicKey(key)\n },\n\n /**\n * 校验私钥格式是否合法\n *\n * 合法格式:64 字符十六进制。\n *\n * @param key - 待校验私钥\n * @returns 格式合法返回 true\n */\n isValidPrivateKey(key: string): boolean {\n if (!key || typeof key !== 'string')\n return false\n // 私钥长度:64 字符\n return SM2_PRIVATE_KEY_REGEX.test(key)\n },\n }\n}\n","/**\n * @h-ai/crypto — SM3 哈希\n *\n * 提供 SM3 消息摘要与 HMAC 操作。\n * @module crypto-sm3\n */\n\nimport type { HaiResult } from '@h-ai/core'\n\nimport type { HashOperations, HashOptions } from './crypto-types.js'\nimport { core, err, ok } from '@h-ai/core'\n// @ts-expect-error sm-crypto 无类型定义\nimport smCrypto from 'sm-crypto'\n\nimport { cryptoM } from './crypto-i18n.js'\nimport {\n HaiCryptoError,\n\n} from './crypto-types.js'\n\nconst { sm3 } = smCrypto\n\n// ─── SM3 算法实现 ───\n\n/**\n * 创建模块内部 SM3 摘要/HMAC 操作;HMAC 使用 SM3,不是 HMAC-SHA256。\n * @returns 同步 HaiResult 操作;调用方判断 success 后读取摘要或匹配结果。\n *\n * @example 模块内部上下文\n * ```ts\n * const hash = createSM3()\n * const digest = hash.hash(new Uint8Array([104, 105]))\n * if (!digest.success) throw new Error(digest.error.message)\n * const verified = hash.verify('hi', digest.data)\n * if (!verified.success) throw new Error(verified.error.message)\n * ```\n */\nexport function createSM3(): HashOperations {\n return {\n /**\n * 计算 SM3 哈希\n *\n * 支持字符串(UTF-8/Hex)和 Uint8Array 输入。\n *\n * @param data - 待哈希数据\n * @param options - 输入编码与输出格式\n * @returns 成功时返回 64 字符十六进制哈希值;失败时返回 HASH_FAILED\n */\n hash(\n data: string | Uint8Array,\n options: HashOptions = {},\n ): HaiResult<string> {\n const { inputEncoding = 'utf8' } = options\n\n try {\n let input: string | number[]\n\n if (data instanceof Uint8Array) {\n // Uint8Array 转为数字数组(sm-crypto 支持的格式)\n input = Array.from(data)\n }\n else if (inputEncoding === 'hex') {\n // 十六进制字符串转为数字数组\n input = hexToBytes(data)\n }\n else {\n // UTF-8 字符串直接传入\n input = data\n }\n\n const result = sm3(input)\n\n if (!result) {\n return err(\n HaiCryptoError.HASH_FAILED,\n cryptoM('crypto_sm3HashEmpty'),\n )\n }\n\n return ok(result)\n }\n catch (error) {\n return err(\n HaiCryptoError.HASH_FAILED,\n cryptoM('crypto_sm3HashFailed', { params: { error: error instanceof Error ? error.message : String(error) } }),\n error,\n )\n }\n },\n\n /**\n * 计算 HMAC-SM3 消息认证码\n *\n * 实现遵循 RFC 2104;密钥超过块大小(64 字节)时先对密钥做哈希。\n *\n * @param data - 待计算数据\n * @param key - HMAC 密钥\n * @returns 成功时返回 64 字符十六进制 HMAC 值;失败时返回 HMAC_FAILED\n */\n hmac(data: string, key: string): HaiResult<string> {\n try {\n const blockSize = 64\n const opad = 0x5C\n const ipad = 0x36\n\n // 处理密钥\n let keyBytes: number[]\n if (key.length > blockSize) {\n const hashedKey = sm3(key)\n keyBytes = hexToBytes(hashedKey)\n }\n else {\n keyBytes = stringToBytes(key)\n }\n\n // 填充密钥到块大小\n while (keyBytes.length < blockSize) {\n keyBytes.push(0)\n }\n\n // 计算 iKeyPad 和 oKeyPad\n const iKeyPad = keyBytes.map(b => b ^ ipad)\n const oKeyPad = keyBytes.map(b => b ^ opad)\n\n // 计算内层哈希:H(iKeyPad || data)\n const innerInput = iKeyPad.concat(stringToBytes(data))\n const innerHash = sm3(innerInput)\n\n // 计算外层哈希:H(oKeyPad || innerHash)\n const outerInput = oKeyPad.concat(hexToBytes(innerHash))\n const result = sm3(outerInput)\n\n return ok(result)\n }\n catch (error) {\n return err(\n HaiCryptoError.HMAC_FAILED,\n cryptoM('crypto_sm3HmacFailed', { params: { error: error instanceof Error ? error.message : String(error) } }),\n error,\n )\n }\n },\n\n /**\n * 验证数据的哈希是否匹配\n *\n * 对数据做 SM3 哈希后与期望值比较(忽略大小写)。\n *\n * @param data - 原始数据\n * @param expectedHash - 期望的哈希值\n * @returns 成功时返回 boolean;失败时返回 HASH_FAILED\n */\n verify(data: string, expectedHash: string): HaiResult<boolean> {\n try {\n const hashResult = sm3(data)\n return ok(core.string.constantTimeEqual(hashResult.toLowerCase(), expectedHash.toLowerCase()))\n }\n catch (error) {\n return err(\n HaiCryptoError.HASH_FAILED,\n cryptoM('crypto_sm3VerifyFailed', { params: { error: error instanceof Error ? error.message : String(error) } }),\n error,\n )\n }\n },\n }\n}\n\n// ─── 辅助函数 ───\n\n/**\n * 内部Hex字节转换,不执行输入校验;上游输入编码约束应在业务边界处理。\n * @param hex - 偶数长度Hex字节文本。\n * @returns 数字字节数组。\n *\n * @example 模块内部上下文\n * ```ts\n * const bytes = hexToBytes('6869')\n * ```\n */\nfunction hexToBytes(hex: string): number[] {\n const bytes: number[] = []\n for (let i = 0; i < hex.length; i += 2) {\n bytes.push(Number.parseInt(hex.slice(i, i + 2), 16))\n }\n return bytes\n}\n\n/**\n * UTF-8 字符串转字节数组\n *\n * 使用 TextEncoder 进行编码转换。\n *\n * @param str - UTF-8 字符串\n * @returns 字节数组\n */\nfunction stringToBytes(str: string): number[] {\n const encoder = new TextEncoder()\n return Array.from(encoder.encode(str))\n}\n","/**\n * @h-ai/crypto — SM4 对称加密\n *\n * 提供 SM4 对称加解密操作(CBC/ECB 模式)。\n * @module crypto-sm4\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type {\n EncryptWithIVResult,\n SymmetricCiphertextEncoding,\n SymmetricDecryptInput,\n SymmetricEncryptedPayload,\n SymmetricEncryptOptions,\n SymmetricOperations,\n} from './crypto-types.js'\n\nimport { err, ok } from '@h-ai/core'\n// @ts-expect-error sm-crypto 无类型定义\nimport smCrypto from 'sm-crypto'\n\nimport { cryptoM } from './crypto-i18n.js'\nimport {\n\n HaiCryptoError,\n\n} from './crypto-types.js'\nimport { base64ToHex, hexToBase64 } from './crypto-utils.js'\n\nconst { sm4 } = smCrypto\nconst SM4_HEX_32_REGEX = /^[0-9a-f]{32}$/i\n\n// ─── SM4 算法实现 ───\n\n/**\n * 创建模块内部 SM4 原语,默认 CBC、随机 IV、PKCS#7 填充,返回结构化密文。\n * CBC/ECB 本身没有完整性认证;HTTP 必须使用 transport 先验签/MAC 再解密。\n * @returns 对称操作;解密需要完整 mode/encoding/iv,不猜测裸字符串。\n *\n * @example 模块内部上下文\n * ```ts\n * const symmetric = createSM4()\n * const key = symmetric.generateKey()\n * const encrypted = symmetric.encrypt('hello', key)\n * if (!encrypted.success) throw new Error(encrypted.error.message)\n * const decrypted = symmetric.decrypt(encrypted.data, key)\n * if (!decrypted.success) throw new Error(decrypted.error.message)\n * ```\n */\nexport function createSM4(): SymmetricOperations {\n return {\n /** 生成随机密钥(16 字节 = 32 个十六进制字符) */\n generateKey(): string {\n return generateRandomHex(16)\n },\n\n /** 生成随机 IV(16 字节 = 32 个十六进制字符) */\n generateIV(): string {\n return generateRandomHex(16)\n },\n\n /**\n * SM4 对称加密\n *\n * 默认使用 CBC 并自动生成随机 IV,返回结构化字段。\n *\n * ⚠️ 安全警告:ECB 模式会让相同明文块产生相同密文块,泄漏结构信息。\n * 新数据使用默认 CBC,或每次显式传入新的随机 IV;CBC 仍需独立完整性认证,HTTP 使用 transport。\n *\n * @param data - 待加密明文\n * @param key - 密钥(32 字符十六进制)\n * @param options - 加密模式/IV/输出格式\n * @returns 成功时返回结构化密文;失败时返回 INVALID_KEY/INVALID_IV/ENCRYPTION_FAILED\n */\n encrypt(\n data: string,\n key: string,\n options: SymmetricEncryptOptions = {},\n ): HaiResult<SymmetricEncryptedPayload> {\n const {\n mode = 'cbc',\n iv,\n outputFormat = 'hex',\n } = options\n const actualIv = mode === 'cbc' ? iv ?? this.generateIV() : undefined\n\n if (!this.isValidKey(key)) {\n return err(\n HaiCryptoError.INVALID_KEY,\n cryptoM('crypto_sm4KeyInvalid'),\n )\n }\n\n if (mode === 'cbc') {\n if (!actualIv || !this.isValidIV(actualIv)) {\n return err(\n HaiCryptoError.INVALID_IV,\n cryptoM('crypto_sm4IvInvalid'),\n )\n }\n }\n\n try {\n const sm4Options: Record<string, unknown> = {\n mode,\n padding: 'pkcs#7',\n }\n\n if (mode === 'cbc' && actualIv) {\n sm4Options.iv = actualIv\n }\n\n const encrypted = sm4.encrypt(data, key, sm4Options)\n\n if (!encrypted) {\n return err(\n HaiCryptoError.ENCRYPTION_FAILED,\n cryptoM('crypto_sm4EncryptEmpty'),\n )\n }\n\n return ok({\n mode,\n ciphertext: encodeCiphertext(encrypted, outputFormat),\n ...(actualIv ? { iv: actualIv } : {}),\n encoding: outputFormat,\n })\n }\n catch (error) {\n return err(\n HaiCryptoError.ENCRYPTION_FAILED,\n cryptoM('crypto_sm4EncryptFailed', { params: { error: error instanceof Error ? error.message : String(error) } }),\n error,\n )\n }\n },\n\n /**\n * SM4 对称解密\n *\n * 使用结构化字段解密;解密模式、IV 与密文编码均来自 payload。\n *\n * @param payload - 结构化密文\n * @param key - 密钥(32 字符十六进制)\n * @returns 成功时返回明文;失败时返回 INVALID_KEY/INVALID_IV/DECRYPTION_FAILED\n */\n decrypt(\n payload: SymmetricDecryptInput,\n key: string,\n ): HaiResult<string> {\n const { mode, iv } = payload\n\n if (!this.isValidKey(key)) {\n return err(\n HaiCryptoError.INVALID_KEY,\n cryptoM('crypto_sm4KeyInvalid'),\n )\n }\n\n if (mode === 'cbc' && (!iv || !this.isValidIV(iv))) {\n return err(\n HaiCryptoError.INVALID_IV,\n cryptoM('crypto_sm4IvInvalid'),\n )\n }\n\n try {\n const input = decodeCiphertext(payload)\n\n const sm4Options: Record<string, unknown> = {\n mode,\n padding: 'pkcs#7',\n }\n\n if (mode === 'cbc' && iv) {\n sm4Options.iv = iv\n }\n\n const decrypted = sm4.decrypt(input, key, sm4Options)\n\n if (decrypted === false || decrypted === null || decrypted === undefined) {\n return err(\n HaiCryptoError.DECRYPTION_FAILED,\n cryptoM('crypto_sm4DecryptFailed'),\n )\n }\n\n return ok(decrypted)\n }\n catch (error) {\n return err(\n HaiCryptoError.DECRYPTION_FAILED,\n cryptoM('crypto_sm4DecryptFailedWithError', { params: { error: error instanceof Error ? error.message : String(error) } }),\n error,\n )\n }\n },\n\n /**\n * 带 IV 加密(CBC 模式,自动生成随机 IV)\n *\n * @param data - 待加密明文\n * @param key - 密钥(32 字符十六进制)\n * @returns 成功时返回完整 { mode, ciphertext, iv, encoding };失败时同 encrypt\n */\n encryptWithIV(\n data: string,\n key: string,\n ): HaiResult<EncryptWithIVResult> {\n const iv = this.generateIV()\n const result = this.encrypt(data, key, { mode: 'cbc', iv })\n\n if (!result.success) {\n return result\n }\n\n return ok({\n mode: 'cbc',\n ciphertext: result.data.ciphertext,\n iv,\n encoding: result.data.encoding,\n })\n },\n\n /**\n * 带 IV 解密(CBC 模式)\n *\n * 这是不含认证的底层 primitive;传输数据必须经 transport 验签及 MAC 后再调用,禁止直接用于 HTTP 解密。\n *\n * @param ciphertext - 密文\n * @param key - 密钥\n * @param iv - 加密时使用的 IV\n * @returns 成功时返回明文;失败时同 decrypt\n */\n decryptWithIV(\n ciphertext: string,\n key: string,\n iv: string,\n ): HaiResult<string> {\n return this.decrypt({ mode: 'cbc', ciphertext, iv, encoding: 'hex' }, key)\n },\n\n /** 校验密钥格式是否合法(32 字符十六进制) */\n isValidKey(key: string): boolean {\n return SM4_HEX_32_REGEX.test(key)\n },\n\n /** 校验 IV 格式是否合法(32 字符十六进制) */\n isValidIV(iv: string): boolean {\n return SM4_HEX_32_REGEX.test(iv)\n },\n }\n}\n\n// ─── 辅助函数 ───\n\n/**\n * 使用宿主Web Crypto生成随机字节并编码为小写Hex,密钥/IV分别调用以保持独立。\n * @param byteLength - 需要的字节数。\n * @returns 长度为byteLength两倍的Hex。\n *\n * @example 模块内部上下文\n * ```ts\n * const key = generateRandomHex(16)\n * const iv = generateRandomHex(16)\n * ```\n */\nfunction generateRandomHex(byteLength: number): string {\n const bytes = new Uint8Array(byteLength)\n // Web Crypto API,前后端通用\n crypto.getRandomValues(bytes)\n return Array.from(bytes)\n .map(b => b.toString(16).padStart(2, '0'))\n .join('')\n}\n\n/** 按输出编码转换 SM4 hex 密文。 */\nfunction encodeCiphertext(ciphertext: string, encoding: SymmetricCiphertextEncoding): string {\n return encoding === 'base64' ? hexToBase64(ciphertext) : ciphertext\n}\n\n/**\n * 按已校验结构的encoding解码密文,不猜测裸字符串或丢弃IV。\n * @param payload - 完整结构化密文。\n * @returns SM4底层所需Hex字节文本。\n *\n * @example 模块内部上下文\n * ```ts\n * const payload: SymmetricDecryptInput = { mode: 'ecb', ciphertext: 'aGk=', encoding: 'base64' }\n * const bytes = decodeCiphertext(payload)\n * // 此例只演示编码转换,不执行ECB加解密,也不是有效的认证封装。\n * ```\n */\nfunction decodeCiphertext(payload: SymmetricDecryptInput): string {\n return payload.encoding === 'base64' ? base64ToHex(payload.ciphertext) : payload.ciphertext\n}\n","/**\n * @h-ai/crypto — 传输协议的字节预算与有界正文读取。\n *\n * serv/kit 共享相同预算,不依赖可省略或伪造的 Content-Length。\n * @module crypto-transport-body\n */\n\nimport { cryptoM } from '../crypto-i18n.js'\nimport { HaiCryptoError } from '../crypto-types.js'\n\n/**\n * 传输预算;业务预算由明文容量推导,安全字段保持独立。\n * @example\n * ```ts\n * import { resolveTransportBodyLimits, type TransportBodyLimits } from '@h-ai/crypto'\n * const limits: TransportBodyLimits = resolveTransportBodyLimits(8 * 1024 * 1024)\n * const proxyBytes = limits.encryptedPayloadBytes\n * ```\n */\nexport interface TransportBodyLimits {\n readonly keyExchangeBytes: number\n readonly envelopeHeaderBytes: number\n readonly publicKeyBytes: number\n readonly plaintextBytes: number\n readonly encryptedPayloadBytes: number\n}\n\n/**\n * 业务明文的有效 UTF-8 字节范围:1 KiB~64 MiB;不支持无限制。\n * @example\n * ```ts\n * import { TRANSPORT_PLAINTEXT_RANGE } from '@h-ai/crypto'\n * const maximumBytes = TRANSPORT_PLAINTEXT_RANGE.max\n * ```\n */\nexport const TRANSPORT_PLAINTEXT_RANGE = Object.freeze({ min: 1024, max: 64 * 1024 * 1024 })\n\n/**\n * 默认UTF-8字节预算;按实际流读取,不依赖Content-Length,非字符串字符数限制。\n *\n * @example\n * ```ts\n * import { readTransportBody, TRANSPORT_BODY_LIMITS } from '@h-ai/crypto'\n * const request = new Request('https://api.example.com/api/v1/orders', { method: 'POST', body: JSON.stringify({ message: 'hello' }) })\n * const text = await readTransportBody(request.body, { maxBytes: TRANSPORT_BODY_LIMITS.plaintextBytes, signal: request.signal })\n * ```\n */\nexport const TRANSPORT_BODY_LIMITS: TransportBodyLimits = Object.freeze({\n /** 密钥协商 JSON 的 UTF-8 总字节数。 */\n keyExchangeBytes: 16_384,\n /** GET/HEAD 请求及无正文响应的认证头封装 UTF-8 上限。 */\n envelopeHeaderBytes: 16_384,\n /** 单个协商公钥的 UTF-8 字节数。 */\n publicKeyBytes: 4096,\n /** 解密后的请求/加密前的响应明文字节数。 */\n plaintextBytes: 1_048_576,\n /** 密文 JSON 的 UTF-8 总字节数(2 MiB + 32 KiB,含 CBC 填充与全部认证字段)。 */\n encryptedPayloadBytes: 2_129_920,\n})\n\n/**\n * 校验单一业务明文容量并推导双向密文预算;返回不可变快照。\n * SM4-CBC 使用十六进制编码,预算为明文的两倍加 32 KiB(填充及认证封装)。\n * @param maxPlaintextBytes - UTF-8 字节数,默认 1 MiB,有效范围 1 KiB~64 MiB 的整数。\n * @param options - 已启用模块所需的最小明文预算;只在宿主未显式设置上限时自动推导。\n * @param options.requiredPlaintextBytes - 模块需要的最小 UTF-8 明文字节数,仍受 1 KiB~64 MiB 范围约束。\n * @returns 明文、密文及独立安全预算。\n * @throws RangeError - 配置无效;不接受字符串、null、无限制或静默回退。\n * @example\n * ```ts\n * import { resolveTransportBodyLimits } from '@h-ai/crypto'\n * const limits = resolveTransportBodyLimits(8 * 1024 * 1024)\n * const nginxLimit = limits.encryptedPayloadBytes\n * ```\n */\nexport function resolveTransportBodyLimits(maxPlaintextBytes?: number, options: { requiredPlaintextBytes?: number } = {}): TransportBodyLimits {\n const required = options.requiredPlaintextBytes\n if (required !== undefined && (!Number.isSafeInteger(required) || required < TRANSPORT_PLAINTEXT_RANGE.min || required > TRANSPORT_PLAINTEXT_RANGE.max))\n throw new RangeError(cryptoM('crypto_transportBodyLimitInvalid'))\n if (maxPlaintextBytes === undefined)\n maxPlaintextBytes = required ?? TRANSPORT_BODY_LIMITS.plaintextBytes\n if (!Number.isSafeInteger(maxPlaintextBytes) || maxPlaintextBytes < TRANSPORT_PLAINTEXT_RANGE.min || maxPlaintextBytes > TRANSPORT_PLAINTEXT_RANGE.max)\n throw new RangeError(cryptoM('crypto_transportBodyLimitInvalid'))\n if (required !== undefined && maxPlaintextBytes < required)\n throw new RangeError(cryptoM('crypto_transportBodyLimitConflict', { params: { limit: maxPlaintextBytes, required } }))\n return Object.freeze({ ...TRANSPORT_BODY_LIMITS, plaintextBytes: maxPlaintextBytes, encryptedPayloadBytes: 2 * maxPlaintextBytes + 32_768 })\n}\n\n/**\n * 可识别的容量错误;只包含方向、阶段和字节数,不包含报文内容。\n * @example\n * ```ts\n * import { TransportBodyTooLargeError } from '@h-ai/crypto'\n * const error = new TransportBodyTooLargeError(1024, 1025, { direction: 'request', stage: 'plaintext' })\n * const diagnostic = { code: error.code, limitBytes: error.limitBytes, actualBytes: error.actualBytes }\n * ```\n */\nexport class TransportBodyTooLargeError extends RangeError {\n readonly code = HaiCryptoError.TRANSPORT_PAYLOAD_TOO_LARGE.code\n readonly direction: 'request' | 'response'\n readonly stage: 'plaintext' | 'encrypted' | 'header'\n readonly limitBytes: number\n readonly actualBytes?: number\n\n constructor(limitBytes: number, actualBytes?: number, options: { direction?: 'request' | 'response', stage?: 'plaintext' | 'encrypted' | 'header' } = {}) {\n super(cryptoM('crypto_transportBodyTooLarge'))\n this.name = 'TransportBodyTooLargeError'\n this.limitBytes = limitBytes\n this.actualBytes = actualBytes\n this.direction = options.direction ?? 'request'\n this.stage = options.stage ?? 'plaintext'\n }\n}\n\n/**\n * 有界原流读取选项;maxBytes是非负安全整数,signal取消等待和底层流。\n *\n * @example\n * ```ts\n * import { readTransportBody, type ReadTransportBodyOptions } from '@h-ai/crypto'\n * const request = new Request('https://api.example.com/api/v1/orders', { method: 'POST', body: 'hello' })\n * const options: ReadTransportBodyOptions = { maxBytes: 1024, signal: request.signal }\n * const text = await readTransportBody(request.body, options)\n * ```\n */\nexport interface ReadTransportBodyOptions {\n /** 允许读取的字节总数,必须为非负安全整数。 */\n readonly maxBytes: number\n /** 请求取消时中止等待中的读取并取消底层流。 */\n readonly signal?: AbortSignal\n /** 超限诊断方向;默认 request。 */\n readonly direction?: 'request' | 'response'\n /** 超限诊断阶段;默认 plaintext。 */\n readonly stage?: 'plaintext' | 'encrypted' | 'header'\n}\n\n/**\n * 逐块读取原始字节流并严格UTF-8解码;超限/取消后取消流并释放reader,清理失败不覆盖原异常。\n * 不要传入clone/tee分支,否则另一分支仍可能保留数据。\n * @param stream - 原始流;null返回空串但仍检查取消。\n * @param options - 字节预算与取消信号。\n * @returns 解码文本。\n * @throws RangeError预算无效或超限;非法UTF-8、流异常和signal.reason继续抛出。\n *\n * @example\n * ```ts\n * import { readTransportBody } from '@h-ai/crypto'\n * const request = new Request('https://api.example.com/api/v1/orders', { method: 'POST', body: 'hello' })\n * const text = await readTransportBody(request.body, { maxBytes: 1024, signal: request.signal })\n * ```\n */\nexport async function readTransportBody(\n stream: ReadableStream<Uint8Array> | null,\n options: ReadTransportBodyOptions,\n): Promise<string> {\n if (!Number.isSafeInteger(options.maxBytes) || options.maxBytes < 0)\n throw new RangeError('Invalid transport body byte limit')\n if (!stream) {\n options.signal?.throwIfAborted()\n return ''\n }\n\n const reader = stream.getReader()\n const signal = options.signal\n const decoder = new TextDecoder('utf-8', { fatal: true })\n let completed = false\n let failure: unknown\n let onAbort: (() => void) | undefined\n try {\n signal?.throwIfAborted()\n const aborted = signal\n ? new Promise<never>((_resolve, reject) => {\n onAbort = () => reject(signal.reason)\n signal.addEventListener('abort', onAbort, { once: true })\n })\n : undefined\n let bytes = 0\n let text = ''\n while (true) {\n const next = reader.read()\n const chunk = await (aborted ? Promise.race([next, aborted]) : next)\n if (chunk.done) {\n completed = true\n return text + decoder.decode()\n }\n bytes += chunk.value.byteLength\n if (bytes > options.maxBytes)\n throw new TransportBodyTooLargeError(options.maxBytes, bytes, options)\n text += decoder.decode(chunk.value, { stream: true })\n }\n }\n catch (error) {\n failure = error\n throw error\n }\n finally {\n if (onAbort)\n signal?.removeEventListener('abort', onAbort)\n if (!completed) {\n // cancel 的底层清理可能拒绝或长期等待,不能覆盖原异常或阻塞拒绝响应。\n try {\n void reader.cancel(failure).catch(() => {})\n }\n catch {}\n }\n reader.releaseLock()\n }\n}\n\n/**\n * 为真实 HTTP 适配器分离业务与大附件容量;* 只匹配一个完整路径段。\n * 单独声明且超过 1 MiB 的材料路由最多两个,普通业务最多十六个,租约须在响应完成或失败时释放。\n * @param maxPlaintextBytes - 普通业务容量;省略使用 1 MiB。\n * @param routes - 受信任的绝对路径到 UTF-8 容量映射,最多 100 条。\n * @returns 协商最大容量及每请求的限额和可释放并发准入。\n * @throws RangeError 配置路径、数量或容量无效。\n * @example\n * ```ts\n * import { createTransportBodyPolicy } from '@h-ai/crypto'\n * const policy = createTransportBodyPolicy(undefined, { '/api/files/*': 8 * 1024 * 1024 })\n * const lease = policy.acquire('/api/files/attachment')\n * try { if (lease) lease.limits.plaintextBytes }\n * finally { lease?.release() }\n * ```\n */\nexport function createTransportBodyPolicy(maxPlaintextBytes?: number, routes: Readonly<Record<string, number>> = {}) {\n const ordinary = resolveTransportBodyLimits(maxPlaintextBytes)\n const entries = Object.entries(routes)\n if (entries.length > 100 || entries.some(([path]) => !path.startsWith('/') || path.includes('?') || path.includes('#') || path.split('/').some(part => part.includes('*') && part !== '*')))\n throw new RangeError(cryptoM('crypto_transportBodyLimitInvalid'))\n const configured = entries.map(([path, bytes]) => ({ parts: path.split('/'), limits: resolveTransportBodyLimits(bytes) }))\n const maximum = resolveTransportBodyLimits(Math.max(ordinary.plaintextBytes, ...configured.map(route => route.limits.plaintextBytes)))\n let small = 0\n let large = 0\n return {\n maximum,\n acquire(pathname: string) {\n const parts = pathname.split('/')\n const matching = configured.filter(route => route.parts.length === parts.length && route.parts.every((part, index) => part === '*' || part === parts[index]))\n // 重叠路由采用更严格容量;既定配置不会因记录顺序改变安全边界。\n const limits = matching.length ? matching.reduce((left, right) => left.limits.plaintextBytes < right.limits.plaintextBytes ? left : right).limits : ordinary\n const heavy = matching.length > 0 && limits.plaintextBytes > TRANSPORT_BODY_LIMITS.plaintextBytes\n if (heavy ? large >= 2 : small >= 16)\n return null\n if (heavy)\n large++\n else\n small++\n let released = false\n return { limits, release() {\n if (released)\n return\n released = true\n if (heavy)\n large--\n else\n small--\n } }\n },\n }\n}\n","/**\n * @h-ai/crypto — 传输加密类型与协议常量\n *\n * 提供 SM2 + SM4(或等效非对称 + 对称)混合传输加密所需的接口与协议常量,\n * 由 kit / serv / api-client 共享,确保两端协议完全一致。\n *\n * @module crypto-transport-types\n */\n\nimport type { HaiResult } from '@h-ai/core'\n\n// ─── 协议常量(kit / serv / api-client 必须严格一致) ───\n\n/**\n * 认证传输v2的头名、窗口与默认协商子路径;各HTTP适配器共用,不手写漂移常量。\n *\n * @example\n * ```ts\n * import { TRANSPORT_PROTOCOL } from '@h-ai/crypto'\n * const headers = new Headers()\n * headers.set(TRANSPORT_PROTOCOL.ENCRYPTED_HEADER, TRANSPORT_PROTOCOL.ENCRYPTED_HEADER_VALUE)\n * const keyExchangePath = TRANSPORT_PROTOCOL.DEFAULT_KEY_EXCHANGE_PATH\n * ```\n */\nexport const TRANSPORT_PROTOCOL = {\n /** 客户端 ID 请求头名。 */\n CLIENT_ID_HEADER: 'X-Client-Id',\n /** GET/HEAD 等无正文请求的认证封装;禁止与正文封装同时出现。 */\n ENVELOPE_HEADER: 'X-Hai-Transport',\n /** 唯一支持的认证协议版本;旧未认证格式拒绝。 */\n VERSION: 2,\n /** 请求允许的过去时间窗口(毫秒)。 */\n REQUEST_WINDOW_MS: 300_000,\n /** 节点时钟允许的最大未来偏差(毫秒)。 */\n CLOCK_SKEW_MS: 30_000,\n /** 标识响应体已加密的响应头名。 */\n ENCRYPTED_HEADER: 'X-Encrypted',\n /** `X-Encrypted` 响应头的开启值。 */\n ENCRYPTED_HEADER_VALUE: 'true',\n /** 密钥协商端点的默认子路径(相对于挂载前缀)。 */\n DEFAULT_KEY_EXCHANGE_PATH: '/_hai/key-exchange',\n} as const\n\n/**\n * 密钥协商请求;只发送客户端公钥,私钥始终留在客户端,注册仍验证曲线点。\n *\n * @example\n * ```ts\n * import { crypto, type KeyExchangeRequest } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const generated = crypto.asymmetric.generateKeyPair()\n * if (!generated.success) throw new Error(generated.error.message)\n * const pair = generated.data\n * const body: KeyExchangeRequest = { clientPublicKey: pair.publicKey }\n * const serialized = JSON.stringify(body)\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport interface KeyExchangeRequest {\n readonly clientPublicKey: string\n}\n\n/**\n * TLS协商响应,公开服务端版本、公钥和registry生成的clientId;不含服务端私钥。\n *\n * @example\n * ```ts\n * import type { KeyExchangeRequest, KeyExchangeResponse, TransportEncryptionManager } from '@h-ai/crypto'\n * async function exchange(manager: TransportEncryptionManager, body: KeyExchangeRequest): Promise<KeyExchangeResponse> {\n * const clientId = await manager.registerClientKey(body.clientPublicKey)\n * return { clientId, serverKeyId: manager.getServerKeyId(), serverPublicKey: manager.getServerPublicKey() }\n * }\n * ```\n */\nexport interface KeyExchangeResponse {\n /** 服务端业务明文 UTF-8 字节上限;缺省表示旧服务端的 1 MiB 默认值。 */\n readonly maxPlaintextBytes?: number\n /** 服务端当前加密密钥版本;业务请求必须带回该值。 */\n readonly serverKeyId: string\n readonly serverPublicKey: string\n readonly clientId: string\n}\n\n// ─── 加解密载荷 ───\n\n/**\n * 传输使用的SM2公私钥对;服务端版本从私有Secret注入,客户端可本地生成独立会话密钥。\n *\n * @example\n * ```ts\n * import { crypto, type TransportKeyPair } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const generated = crypto.asymmetric.generateKeyPair()\n * if (!generated.success) throw new Error(generated.error.message)\n * const pair = generated.data\n * const clientPair: TransportKeyPair = pair\n * const publicKey = clientPair.publicKey\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport interface TransportKeyPair {\n readonly publicKey: string\n readonly privateKey: string\n}\n\n/**\n * 完整v2认证封装;encryptedKey含独立SM4/HMAC密钥,signature覆盖认证字段和MAC。\n * HTTP适配器只用成功认证得到的上下文生成响应,不自行拼接示例密文。\n *\n * @example\n * ```ts\n * import { authenticateTransportRequest, type EncryptedPayload, type TransportEncryptionManager } from '@h-ai/crypto'\n * async function sealResponse(manager: TransportEncryptionManager, request: Request): Promise<EncryptedPayload> {\n * const verified = await authenticateTransportRequest(manager, request)\n * if (!verified.success) throw new Error(verified.error.message)\n * const encrypted = await manager.encryptResponse(verified.data.context, JSON.stringify({ accepted: true }), 200)\n * if (!encrypted.success) throw new Error(encrypted.error.message)\n * return encrypted.data\n * }\n * ```\n */\nexport interface EncryptedPayload {\n /** 认证的请求上下文;响应必须原样关联同一个请求。 */\n readonly context: TransportMessageContext\n /** 认证方向,防止把合法响应反射到请求入口。 */\n readonly direction: 'request' | 'response'\n /** 请求固定为 0;响应认证实际 HTTP 状态码。 */\n readonly status: number\n /** SM2 封装的 JSON [SM4 密钥 hex, 独立 HMAC 密钥 hex]。 */\n readonly encryptedKey: string\n /** SM4-CBC 密文 hex;认证输入包含原始编码值。 */\n readonly ciphertext: string\n /** 随机 16 字节 CBC IV 的 hex 编码。 */\n readonly iv: string\n /** 独立随机密钥计算的 HMAC-SM3;先验证后解密 CBC。 */\n readonly tag: string\n /** 对完整封装和 tag 的发送方 SM2 签名,防止公钥持有者伪造发送方。 */\n readonly signature: string\n}\n\n/**\n * 认证的单次HTTP上下文;128位nonce、版本、客户端、时间、方法和实际路径SM3摘要共同绑定。\n * 服务端共享registry只允许消费一次nonce;响应必须关联成功认证后的同一上下文。\n *\n * @example\n * ```ts\n * import { authenticateTransportRequest, type TransportEncryptionManager, type TransportMessageContext } from '@h-ai/crypto'\n * async function contextOf(manager: TransportEncryptionManager, request: Request): Promise<TransportMessageContext> {\n * const verified = await authenticateTransportRequest(manager, request)\n * if (!verified.success) throw new Error(verified.error.message)\n * return verified.data.context\n * }\n * ```\n */\nexport interface TransportMessageContext {\n /** 唯一受支持的协议版本。 */\n readonly version: 2\n /** 协商选择的受管服务端密钥版本。 */\n readonly serverKeyId: string\n /** registry 注册的客户端 ID;发送方必须证明持有对应私钥。 */\n readonly clientId: string\n /** 128 位随机十六进制 nonce,同时用于响应关联。 */\n readonly requestId: string\n /** 请求创建时间,Unix 毫秒;允许过去 5 分钟、未来 30 秒。 */\n readonly issuedAt: number\n /** 大写 HTTP 方法,必须与实际 Request 完全一致。 */\n readonly method: string\n /** 实际 pathname + 原始 search 的 SM3 摘要,64 位小写 hex,避免在认证头中重复长 URL。 */\n readonly pathHash: string\n}\n\n/**\n * 从实际HTTP Request提取的可信绑定输入;不能直接复制密文的自报方法、路径或客户端。\n *\n * @example\n * ```ts\n * import type { TransportRequestContext } from '@h-ai/crypto'\n * function expectedContext(request: Request): TransportRequestContext {\n * const clientId = request.headers.get('X-Client-Id')\n * if (!clientId) throw new Error('Missing client ID')\n * const url = new URL(request.url)\n * return { clientId, method: request.method, path: url.pathname + url.search }\n * }\n * ```\n */\nexport interface TransportRequestContext {\n /** 实际 X-Client-Id 头,用于 registry 查询及发送方验签。 */\n readonly clientId: string\n /** 实际 Request.method。 */\n readonly method: string\n /** 实际 URL.pathname + URL.search,保留查询参数顺序及编码。 */\n readonly path: string\n}\n\n/**\n * 客户端发出的完整请求封装,direction=request且status=0;结构类型不构成认证证明。\n *\n * @example\n * ```ts\n * import type { EncryptedRequestPayload, TransportEncryptionManager } from '@h-ai/crypto'\n * async function decrypt(manager: TransportEncryptionManager, request: Request, payload: EncryptedRequestPayload): Promise<string> {\n * const clientId = request.headers.get('X-Client-Id')\n * if (!clientId) throw new Error('Missing client ID')\n * const url = new URL(request.url)\n * const result = await manager.decryptRequest(payload, { clientId, method: request.method, path: url.pathname + url.search })\n * if (!result.success) throw new Error(result.error.message)\n * return result.data\n * }\n * ```\n */\nexport interface EncryptedRequestPayload extends EncryptedPayload {\n readonly direction: 'request'\n readonly status: 0\n}\n\n/**\n * 服务端受管版本密钥环;所有节点同版本对应同密钥,新协商选activeKeyId,旧版本保留到撤销。\n * 先分发新旧版本再切活动ID;删除旧版本即撤销,私钥不进入PUBLIC_/VITE_/日志。\n *\n * @example\n * ```ts\n * import { parseTransportServerKeyRing, type TransportServerKeyRing } from '@h-ai/crypto'\n * const parsed = parseTransportServerKeyRing(process.env.HAI_CRYPTO_TRANSPORT_SERVERKEYRING)\n * if (!parsed.success) throw new Error(parsed.error.message)\n * const ring: TransportServerKeyRing = parsed.data\n * ```\n */\nexport interface TransportServerKeyRing {\n /** 新协商使用的版本;1–64 个字母、数字、下划线或连字符。 */\n readonly activeKeyId: string\n /** ID 与密钥对;仅供服务端保管,所有节点必须分发相同版本的相同密钥。 */\n readonly keys: Readonly<Record<string, TransportKeyPair>>\n}\n\n// ─── 注入式服务接口 ───\n\n/**\n * 传输协议实际需要的SM2/SM3/HMAC/SM4能力;可结构化注入真实crypto,不仿造另一套算法。\n *\n * @example\n * ```ts\n * import { crypto, type TransportCryptoServiceLike } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const service: TransportCryptoServiceLike = crypto\n * const digest = service.hash.hash('/api/v1/orders')\n * if (!digest.success) throw new Error(digest.error.message)\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport interface TransportCryptoServiceLike {\n asymmetric: {\n generateKeyPair: () => HaiResult<TransportKeyPair>\n encrypt: (data: string, publicKey: string) => HaiResult<string>\n decrypt: (ciphertext: string, privateKey: string) => HaiResult<string>\n sign: (data: string, privateKey: string) => HaiResult<string>\n verify: (data: string, signature: string, publicKey: string) => HaiResult<boolean>\n }\n hash: {\n /** SM3 摘要,用于实际请求路径绑定,不使用其它摘要算法替换。 */\n hash: (data: string) => HaiResult<string>\n hmac: (data: string, key: string) => HaiResult<string>\n }\n symmetric: {\n generateKey: () => string\n encryptWithIV: (data: string, key: string) => HaiResult<{ ciphertext: string, iv: string }>\n decryptWithIV: (ciphertext: string, key: string, iv: string) => HaiResult<string>\n }\n}\n\n// ─── 客户端密钥存储(可插拔,支持分布式) ───\n\n/**\n * 客户端公钥与nonce存储契约;生产显式共享Redis/数据库,真实共享与原子性由提供者保证。\n * get的故障不能当未注册,claimRequest故障不能当成功;有效nonce不得在expiresAt前驱逐。\n *\n * @example\n * ```ts\n * import { crypto, createRedisTransportKeyStore, parseTransportServerKeyRing } from '@h-ai/crypto'\n * import { cache } from '@h-ai/cache'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const connected = await cache.init({ type: 'redis', host: 'cache', port: 6379, password: process.env.HAI_CACHE_PASSWORD })\n * if (!connected.success) throw new Error(connected.error.message)\n * try {\n * const registry = createRedisTransportKeyStore({ cache, ttlSeconds: 3600 })\n * const store: import('@h-ai/crypto').TransportKeyStore = registry\n * const scope = store.stateScope\n * // Redis部署须noeviction/可靠持久化,并同步各节点时钟。\n * }\n * finally { await cache.close() }\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport interface TransportKeyStore {\n /** 公钥与nonce状态的真实共享能力;生产只接受shared。 */\n readonly stateScope: 'local' | 'shared'\n /**\n * 注册有效 SM2 公钥,返回服务端生成的 clientId;格式/曲线点无效或存储故障必须 reject。\n * 容量策略见具体工厂契约:数据库满容量拒绝,开发/测试内存实现允许 FIFO 淘汰公钥。\n * @param publicKey - 实际调用输入,按该方法约束验证。\n * @returns 异步操作结果;存储或网络故障按方法契约拒绝。\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const generated = crypto.asymmetric.generateKeyPair()\n * if (!generated.success) throw new Error(generated.error.message)\n * const pair = generated.data\n * const { createInMemoryKeyStore } = await import('@h-ai/crypto')\n * const registry = createInMemoryKeyStore(100)\n * try { const clientId = await registry.register(pair.publicKey) }\n * finally { await registry.close?.() }\n * // 本例仅开发/测试;生产替换为共享Redis/数据库registry。\n * }\n * finally { await crypto.close() }\n * ```\n */\n register: (publicKey: string) => Promise<string>\n /**\n * 读取已注册有效公钥;缺失返回undefined,存储失败拒绝,不能伪装未注册。\n * @param clientId - registry生成的客户端标识。\n * @returns 异步操作结果;存储或网络故障按方法契约拒绝。\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const generated = crypto.asymmetric.generateKeyPair()\n * if (!generated.success) throw new Error(generated.error.message)\n * const pair = generated.data\n * const { createInMemoryKeyStore } = await import('@h-ai/crypto')\n * const registry = createInMemoryKeyStore(100)\n * try { const clientId = await registry.register(pair.publicKey); const publicKey = await registry.get(clientId) }\n * finally { await registry.close?.() }\n * }\n * finally { await crypto.close() }\n * ```\n */\n get: (clientId: string) => Promise<string | undefined>\n /**\n * 原子消费客户端 requestId nonce;成功返回 true,重放返回 false。\n * 必须跨节点共享且在 expiresAt(Unix 毫秒)前不驱逐;存储故障必须 reject,禁止当作成功。\n * @param clientId - registry生成的客户端标识。\n * @param requestId - 本次128位随机nonce。\n * @param expiresAt - nonce至少保留到的Unix毫秒期限。\n * @returns 异步操作结果;存储或网络故障按方法契约拒绝。\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const generated = crypto.asymmetric.generateKeyPair()\n * if (!generated.success) throw new Error(generated.error.message)\n * const pair = generated.data\n * const { createInMemoryKeyStore } = await import('@h-ai/crypto')\n * const registry = createInMemoryKeyStore(100)\n * try {\n * const clientId = await registry.register(pair.publicKey)\n * const requestId = globalThis.crypto.randomUUID().replaceAll('-', '')\n * const expiresAt = Date.now() + 360000\n * const first = await registry.claimRequest(clientId, requestId, expiresAt)\n * const replay = await registry.claimRequest(clientId, requestId, expiresAt)\n * // 单进程测试预期true/false;生产需要跨节点共享原子消费且有效期间不驱逐。\n * }\n * finally { await registry.close?.() }\n * }\n * finally { await crypto.close() }\n * ```\n */\n claimRequest: (clientId: string, requestId: string, expiresAt: number) => Promise<boolean>\n /**\n * 主动删除(可选,便于客户端登出时清理)。\n * @param clientId - registry生成的客户端标识。\n * @returns 异步操作结果;存储或网络故障按方法契约拒绝。\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const generated = crypto.asymmetric.generateKeyPair()\n * if (!generated.success) throw new Error(generated.error.message)\n * const pair = generated.data\n * const { createInMemoryKeyStore } = await import('@h-ai/crypto')\n * const registry = createInMemoryKeyStore(100)\n * try { const clientId = await registry.register(pair.publicKey); await registry.delete?.(clientId) }\n * finally { await registry.close?.() }\n * }\n * finally { await crypto.close() }\n * ```\n */\n delete?: (clientId: string) => Promise<void>\n /**\n * 可选释放registry自有资源;借用的cache/reldb不由registry关闭。\n * @returns 异步操作结果;存储或网络故障按方法契约拒绝。\n *\n * @example\n * ```ts\n * import { createInMemoryKeyStore } from '@h-ai/crypto'\n * const registry = createInMemoryKeyStore(100)\n * await registry.close?.()\n * // 共享registry借用的cache/reldb仍由应用反序关闭。\n * ```\n */\n close?: () => Promise<void>\n}\n\n/**\n * 服务端创建配置;受管密钥环和共享registry均必填,没有进程随机密钥回退。\n *\n * @example\n * ```ts\n * import { crypto, createRedisTransportKeyStore, parseTransportServerKeyRing } from '@h-ai/crypto'\n * import { cache } from '@h-ai/cache'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const connected = await cache.init({ type: 'redis', host: 'cache', port: 6379, password: process.env.HAI_CACHE_PASSWORD })\n * if (!connected.success) throw new Error(connected.error.message)\n * try {\n * const registry = createRedisTransportKeyStore({ cache, ttlSeconds: 3600 })\n * const parsed = parseTransportServerKeyRing(process.env.HAI_CRYPTO_TRANSPORT_SERVERKEYRING)\n * if (!parsed.success) throw new Error(parsed.error.message)\n * const options: import('@h-ai/crypto').TransportCreateServerOptions = { serverKeyRing: parsed.data, keyStore: registry }\n * const created = crypto.transport.createServer(options)\n * if (!created.success) throw new Error(created.error.message)\n * await created.data.close()\n * }\n * finally { await cache.close() }\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport interface TransportCreateServerOptions {\n /** 双向业务明文 UTF-8 字节上限;默认 1 MiB,整数范围 1 KiB~64 MiB。 */\n readonly maxPlaintextBytes?: number\n /** 必填受管服务端密钥环;没有隐式随机生成或进程密钥回退。 */\n readonly serverKeyRing: TransportServerKeyRing\n /** 客户端公钥存储;生产必须注入跨节点共享实现。 */\n readonly keyStore: TransportKeyStore\n}\n\n// ─── 管理器与客户端公开接口 ───\n\n/**\n * 服务端认证传输管理器;注册公钥,按真实HTTP上下文验签/MAC/时效并消费nonce,随后才返回明文。\n * 优先使用authenticateTransportRequest;响应只用已认证上下文。close释放registry自有资源,不关闭借用的cache/reldb。\n *\n * @example\n * ```ts\n * import { crypto, createRedisTransportKeyStore, parseTransportServerKeyRing } from '@h-ai/crypto'\n * import { cache } from '@h-ai/cache'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const connected = await cache.init({ type: 'redis', host: 'cache', port: 6379, password: process.env.HAI_CACHE_PASSWORD })\n * if (!connected.success) throw new Error(connected.error.message)\n * try {\n * const registry = createRedisTransportKeyStore({ cache, ttlSeconds: 3600 })\n * const ring = parseTransportServerKeyRing(process.env.HAI_CRYPTO_TRANSPORT_SERVERKEYRING)\n * if (!ring.success) throw new Error(ring.error.message)\n * const created = crypto.transport.createServer({ serverKeyRing: ring.data, keyStore: registry })\n * if (!created.success) throw new Error(created.error.message)\n * const manager = created.data\n * try {\n * const currentVersion = manager.getServerKeyId()\n * const publicKey = manager.getServerPublicKey()\n * }\n * finally { await manager.close() }\n * }\n * finally { await cache.close() }\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport interface TransportEncryptionManager {\n /** 本管理器不可变的双向预算;由 maxPlaintextBytes 推导,安全预算独立。 */\n readonly bodyLimits: import('./crypto-transport-body.js').TransportBodyLimits\n /**\n * 当前新协商使用的服务端密钥 ID。\n * @returns 直接返回值,使用前先初始化模块。\n *\n * @example\n * ```ts\n * import type { TransportEncryptionManager } from '@h-ai/crypto'\n * function activeVersion(manager: TransportEncryptionManager): string { return manager.getServerKeyId() }\n * ```\n */\n getServerKeyId: () => string\n /**\n * 返回当前活动版本的公开公钥,只用于可信TLS协商,不含私钥。\n * @returns 直接返回值,使用前先初始化模块。\n *\n * @example\n * ```ts\n * import type { TransportEncryptionManager } from '@h-ai/crypto'\n * function activePublicKey(manager: TransportEncryptionManager): string { return manager.getServerPublicKey() }\n * ```\n */\n getServerPublicKey: () => string\n /**\n * 验证 SM2 公钥编码和曲线点后向显式 registry 注册。\n * @throws 公钥无效或 registry 写入失败;HTTP 协商适配器负责转换成失败响应。\n * @param clientPublicKey - 实际调用输入,按该方法约束验证。\n * @returns 异步操作结果;存储或网络故障按方法契约拒绝。\n *\n * @example\n * ```ts\n * import type { TransportEncryptionManager } from '@h-ai/crypto'\n * async function register(manager: TransportEncryptionManager, clientPublicKey: string): Promise<string> {\n * // 方法校验编码/曲线点后写入共享registry;异常由HTTP协商适配器转成失败响应。\n * return manager.registerClientKey(clientPublicKey)\n * }\n * ```\n */\n registerClientKey: (clientPublicKey: string) => Promise<string>\n /**\n * 查询客户端公钥;registry 读取故障会 reject,不作为未注册处理。\n * @param clientId - registry生成的客户端标识。\n * @returns 异步操作结果;存储或网络故障按方法契约拒绝。\n *\n * @example\n * ```ts\n * import type { TransportEncryptionManager } from '@h-ai/crypto'\n * async function lookup(manager: TransportEncryptionManager, clientId: string): Promise<string | undefined> {\n * return manager.getClientPublicKey(clientId)\n * }\n * ```\n */\n getClientPublicKey: (clientId: string) => Promise<string | undefined>\n /**\n * 按已认证请求上下文加密、MAC 并签名响应,绑定实际 HTTP 状态。\n * registry 及加密故障均返回失败 HaiResult;上下文只能来自成功的请求认证。\n * @param request - 实际调用输入,按该方法约束验证。\n * @param data - 实际调用输入,按该方法约束验证。\n * @param status - 实际调用输入,按该方法约束验证。\n * @returns HaiResult,先检查success再读取data。\n *\n * @example\n * ```ts\n * import { authenticateTransportRequest, type EncryptedPayload, type TransportEncryptionManager } from '@h-ai/crypto'\n * async function sealResponse(manager: TransportEncryptionManager, request: Request): Promise<EncryptedPayload> {\n * const verified = await authenticateTransportRequest(manager, request)\n * if (!verified.success) throw new Error(verified.error.message)\n * const encrypted = await manager.encryptResponse(verified.data.context, JSON.stringify({ accepted: true }), 200)\n * if (!encrypted.success) throw new Error(encrypted.error.message)\n * return encrypted.data\n * }\n * ```\n */\n encryptResponse: (request: TransportMessageContext, data: string, status: number) => Promise<HaiResult<EncryptedPayload>>\n /**\n * 验证发送方、MAC、HTTP 绑定和时效,原子消费 nonce 后才返回明文;错误不含密文或 Secret。\n * expected 须从实际 Request 提取,不从 payload 复制。HTTP 优先用 authenticateTransportRequest。\n * @param payload - 实际调用输入,按该方法约束验证。\n * @param expected - 实际调用输入,按该方法约束验证。\n * @returns HaiResult,先检查success再读取data。\n *\n * @example\n * ```ts\n * import type { EncryptedRequestPayload, TransportEncryptionManager } from '@h-ai/crypto'\n * async function decrypt(manager: TransportEncryptionManager, request: Request, payload: EncryptedRequestPayload): Promise<string> {\n * const clientId = request.headers.get('X-Client-Id')\n * if (!clientId) throw new Error('Missing client ID')\n * const url = new URL(request.url)\n * const result = await manager.decryptRequest(payload, { clientId, method: request.method, path: url.pathname + url.search })\n * if (!result.success) throw new Error(result.error.message)\n * return result.data\n * }\n * ```\n */\n decryptRequest: (payload: EncryptedRequestPayload, expected: TransportRequestContext) => Promise<HaiResult<string>>\n /**\n * 释放registry自有资源;应用仍负责借用cache/reldb的关闭。\n * @returns 异步操作结果;存储或网络故障按方法契约拒绝。\n *\n * @example\n * ```ts\n * import { crypto, createRedisTransportKeyStore, parseTransportServerKeyRing } from '@h-ai/crypto'\n * import { cache } from '@h-ai/cache'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const connected = await cache.init({ type: 'redis', host: 'cache', port: 6379, password: process.env.HAI_CACHE_PASSWORD })\n * if (!connected.success) throw new Error(connected.error.message)\n * try {\n * const registry = createRedisTransportKeyStore({ cache, ttlSeconds: 3600 })\n * const ring = parseTransportServerKeyRing(process.env.HAI_CRYPTO_TRANSPORT_SERVERKEYRING)\n * if (!ring.success) throw new Error(ring.error.message)\n * const created = crypto.transport.createServer({ serverKeyRing: ring.data, keyStore: registry })\n * if (!created.success) throw new Error(created.error.message)\n * const manager = created.data\n * try {\n * const currentVersion = manager.getServerKeyId()\n * const publicKey = manager.getServerPublicKey()\n * }\n * finally { await manager.close() }\n * }\n * finally { await cache.close() }\n * }\n * finally { await crypto.close() }\n * ```\n */\n close: () => Promise<void>\n}\n\n/**\n * 客户端单会话;首次调用自动协商,后续请求生成随机nonce并认证响应关联/签名/MAC。\n * init返回HaiResult;encryptedFetch按fetch契约reject;destroy清本地会话,不代表撤销服务端registry。\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const client = crypto.transport.createClient({ keyExchangeUrl: 'https://api.example.com/api/v1/_hai/key-exchange' })\n * try {\n * const ready = await client.init()\n * if (!ready.success) throw new Error(ready.error.message)\n * const response = await client.encryptedFetch('https://api.example.com/api/v1/orders')\n * if (!response.ok) throw new Error('HTTP request failed')\n * }\n * finally { client.destroy() }\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport interface TransportClient {\n /**\n * 完成密钥协商;多次调用幂等(同一会话只协商一次)。\n *\n * 通常无需手动调用:`encryptedFetch` 在首次请求前会自动 `init()`。\n * 协商在 30 秒内完成,握手 JSON 与单个公钥分别受 TRANSPORT_BODY_LIMITS 限制。\n * @returns HaiResult,先检查success再读取data。\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const client = crypto.transport.createClient({ keyExchangeUrl: 'https://api.example.com/api/v1/_hai/key-exchange' })\n * try {\n * const ready = await client.init()\n * if (!ready.success) throw new Error(ready.error.message)\n * const response = await client.encryptedFetch('https://api.example.com/api/v1/orders')\n * if (!response.ok) throw new Error('HTTP request failed')\n * }\n * finally { client.destroy() }\n * }\n * finally { await crypto.close() }\n * ```\n */\n init: () => Promise<HaiResult<void>>\n /**\n * 包装后的 fetch;签名与全局 `fetch` 一致,请求/响应自动加解密。\n * 明文/密文按 TRANSPORT_BODY_LIMITS 有界读取原流;超限或取消释放 reader,保留调用方 signal。\n * 仅接受关联同一请求上下文与 HTTP status 的认证响应;缺标记也拒绝,不回退明文或密文。\n *\n * @throws 与原生 fetch 一样,网络错误、密钥协商失败、加密失败或解密失败会 reject。\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const client = crypto.transport.createClient({ keyExchangeUrl: 'https://api.example.com/api/v1/_hai/key-exchange' })\n * try {\n * const ready = await client.init()\n * if (!ready.success) throw new Error(ready.error.message)\n * const response = await client.encryptedFetch('https://api.example.com/api/v1/orders')\n * if (!response.ok) throw new Error('HTTP request failed')\n * }\n * finally { client.destroy() }\n * }\n * finally { await crypto.close() }\n * ```\n */\n encryptedFetch: typeof fetch\n /**\n * 是否已完成密钥协商。\n * @returns 直接boolean,false表示不匹配/未就绪。\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const client = crypto.transport.createClient({ keyExchangeUrl: 'https://api.example.com/api/v1/_hai/key-exchange' })\n * try { const ready = client.ready() }\n * finally { client.destroy() }\n * }\n * finally { await crypto.close() }\n * ```\n */\n ready: () => boolean\n /**\n * 清空本地客户端密钥与协商状态;下次请求重新协商,不撤销服务端身份或业务效果。\n * @returns 直接返回值,使用前先初始化模块。\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const client = crypto.transport.createClient({ keyExchangeUrl: 'https://api.example.com/api/v1/_hai/key-exchange' })\n * client.destroy()\n * // 只清本地会话;不撤销服务端registry或业务会话。\n * }\n * finally { await crypto.close() }\n * ```\n */\n destroy: () => void\n}\n","/**\n * @h-ai/crypto — 两端共用的认证传输封装。\n * 独立随机密钥执行 SM4-CBC Encrypt-then-HMAC-SM3,SM2 签名证明发送方持有私钥。\n * @module crypto-transport-codec\n */\nimport type { HaiResult } from '@h-ai/core'\nimport type { TransportBodyLimits } from './crypto-transport-body.js'\nimport type { EncryptedPayload, TransportCryptoServiceLike, TransportMessageContext } from './crypto-transport-types.js'\nimport { core, err, ok } from '@h-ai/core'\nimport { cryptoM } from '../crypto-i18n.js'\nimport { HaiCryptoError } from '../crypto-types.js'\nimport { TRANSPORT_BODY_LIMITS, TransportBodyTooLargeError } from './crypto-transport-body.js'\nimport { TRANSPORT_PROTOCOL } from './crypto-transport-types.js'\n\n/** 固定位置数组防止对象属性顺序、字段拼接或查询参数边界产生歧义。 */\nfunction authenticatedText(payload: Omit<EncryptedPayload, 'tag' | 'signature'>): string {\n const c = payload.context\n return JSON.stringify([\n 'hai-transport',\n c.version,\n payload.direction,\n c.serverKeyId,\n c.clientId,\n c.requestId,\n c.issuedAt,\n c.method,\n c.pathHash,\n payload.status,\n payload.encryptedKey,\n payload.ciphertext,\n payload.iv,\n ])\n}\n\n/**\n * 内部统一认证失败,避免向对端区分签名、MAC、密钥或CBC错误。\n * @returns 脱敏失败HaiResult,不附明文/密钥/密文。\n *\n * @example 模块内部上下文\n * ```ts\n * const failure = transportAuthenticationFailure()\n * if (!failure.success) { const code = failure.error.code }\n * ```\n */\nexport function transportAuthenticationFailure(): HaiResult<never> {\n return err(HaiCryptoError.INVALID_INPUT, cryptoM('crypto_transportAuthenticationFailed'))\n}\n\n/**\n * 内部计算实际pathname+原始search的SM3绑定摘要;不解码、重排查询参数,UTF-8最多8192字节。\n * @param service - SM3能力实现。\n * @param path - 实际pathname与原始search拼接值。\n * @returns SM3摘要或统一失败。\n *\n * @example 模块内部上下文\n * ```ts\n * const { crypto } = await import('@h-ai/crypto')\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const url = new URL('https://api.example.com/api/v1/orders?sort=created')\n * const digest = hashTransportPath(crypto, url.pathname + url.search)\n * if (!digest.success) throw new Error(digest.error.message)\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport function hashTransportPath(service: TransportCryptoServiceLike, path: string): HaiResult<string> {\n try {\n if (!path.startsWith('/') || new TextEncoder().encode(path).byteLength > 8192)\n return transportAuthenticationFailure()\n const digest = service.hash.hash(path)\n return digest.success && /^[a-f0-9]{64}$/.test(digest.data) ? digest : transportAuthenticationFailure()\n }\n catch {\n return transportAuthenticationFailure()\n }\n}\n\n/**\n * 内部生成独立SM4/MAC密钥,以SM2封装并签名完整认证字段;调用方另维护可信HTTP上下文。\n * @param service - 已初始化的SM2/SM3/SM4能力。\n * @param plaintext - 已按协议限制字节预算的明文。\n * @param context - 本次可信绑定上下文。\n * @param direction - request或response认证方向。\n * @param status - 请求0;响应实际HTTP状态。\n * @param recipientPublicKey - 可信接收方公钥。\n * @param senderPrivateKey - 仅本方持有的私钥。\n * @returns 完整认证封装或统一失败;不代替服务端nonce原子消费。\n *\n * @example 模块内部上下文\n * ```ts\n * const { crypto } = await import('@h-ai/crypto')\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const generated = crypto.asymmetric.generateKeyPair()\n * if (!generated.success) throw new Error(generated.error.message)\n * const pair = generated.data\n * const digest = crypto.hash.hash('/api/v1/orders?sort=created')\n * if (!digest.success) throw new Error(digest.error.message)\n * const context: TransportMessageContext = { version: 2, serverKeyId: 'v1', clientId: 'client-test', requestId: globalThis.crypto.randomUUID().replaceAll('-', ''), issuedAt: Date.now(), method: 'POST', pathHash: digest.data }\n * const sealed = sealTransportPayload(crypto, 'hello', context, 'request', 0, pair.publicKey, pair.privateKey)\n * if (!sealed.success) throw new Error(sealed.error.message)\n * const payload = sealed.data\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport function sealTransportPayload(\n service: TransportCryptoServiceLike,\n plaintext: string,\n context: TransportMessageContext,\n direction: EncryptedPayload['direction'],\n status: number,\n recipientPublicKey: string,\n senderPrivateKey: string,\n limits: TransportBodyLimits = TRANSPORT_BODY_LIMITS,\n): HaiResult<EncryptedPayload> {\n try {\n const bytes = new TextEncoder().encode(plaintext).byteLength\n if (bytes > limits.plaintextBytes)\n return err(HaiCryptoError.TRANSPORT_PAYLOAD_TOO_LARGE, cryptoM('crypto_transportBodyTooLarge'), new TransportBodyTooLargeError(limits.plaintextBytes, bytes, { direction }))\n const encryptionKey = service.symmetric.generateKey()\n // MAC 使用独立的 256 位随机密钥,禁止直接复用 SM4 密钥。\n const authenticationKey = service.symmetric.generateKey() + service.symmetric.generateKey()\n const encrypted = service.symmetric.encryptWithIV(plaintext, encryptionKey)\n const wrapped = service.asymmetric.encrypt(JSON.stringify([encryptionKey, authenticationKey]), recipientPublicKey)\n if (!encrypted.success || !wrapped.success)\n return transportAuthenticationFailure()\n const payload = { context: { ...context }, direction, status, encryptedKey: wrapped.data, ciphertext: encrypted.data.ciphertext, iv: encrypted.data.iv }\n const text = authenticatedText(payload)\n const tag = service.hash.hmac(text, authenticationKey)\n if (!tag.success)\n return transportAuthenticationFailure()\n const signature = service.asymmetric.sign(JSON.stringify([text, tag.data]), senderPrivateKey)\n if (!signature.success)\n return transportAuthenticationFailure()\n const authenticated = { ...payload, tag: tag.data, signature: signature.data }\n return isValidEncryptedPayload(authenticated, limits) ? ok(authenticated) : transportAuthenticationFailure()\n }\n catch {\n return transportAuthenticationFailure()\n }\n}\n\n/**\n * 内部按验签→解封密钥→常量时间MAC校验→CBC解密处理;未认证数据不进入CBC。\n * @param service - 已初始化的SM2/SM3/SM4能力。\n * @param payload - 待校验封装。\n * @param recipientPrivateKey - 本方私钥。\n * @param senderPublicKey - 已认证绑定的发送方公钥。\n * @returns 明文或统一失败;HTTP绑定/时效/nonce还须由外层管理器检查。\n *\n * @example 模块内部上下文\n * ```ts\n * const { crypto } = await import('@h-ai/crypto')\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const generated = crypto.asymmetric.generateKeyPair()\n * if (!generated.success) throw new Error(generated.error.message)\n * const pair = generated.data\n * const digest = crypto.hash.hash('/api/v1/orders?sort=created')\n * if (!digest.success) throw new Error(digest.error.message)\n * const context: TransportMessageContext = { version: 2, serverKeyId: 'v1', clientId: 'client-test', requestId: globalThis.crypto.randomUUID().replaceAll('-', ''), issuedAt: Date.now(), method: 'POST', pathHash: digest.data }\n * const sealed = sealTransportPayload(crypto, 'hello', context, 'request', 0, pair.publicKey, pair.privateKey)\n * if (!sealed.success) throw new Error(sealed.error.message)\n * const opened = openTransportPayload(crypto, sealed.data, pair.privateKey, pair.publicKey)\n * if (!opened.success) throw new Error(opened.error.message)\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport function openTransportPayload(\n service: TransportCryptoServiceLike,\n payload: EncryptedPayload,\n recipientPrivateKey: string,\n senderPublicKey: string,\n limits: TransportBodyLimits = TRANSPORT_BODY_LIMITS,\n): HaiResult<string> {\n try {\n if (!isValidEncryptedPayload(payload, limits))\n return transportAuthenticationFailure()\n const text = authenticatedText(payload)\n const verified = service.asymmetric.verify(JSON.stringify([text, payload.tag]), payload.signature, senderPublicKey)\n if (!verified.success || !verified.data)\n return transportAuthenticationFailure()\n const unwrapped = service.asymmetric.decrypt(payload.encryptedKey, recipientPrivateKey)\n if (!unwrapped.success)\n return transportAuthenticationFailure()\n const keys: unknown = JSON.parse(unwrapped.data)\n if (!Array.isArray(keys) || keys.length !== 2\n || typeof keys[0] !== 'string' || !/^[a-f0-9]{32}$/.test(keys[0])\n || typeof keys[1] !== 'string' || !/^[a-f0-9]{64}$/.test(keys[1])) {\n return transportAuthenticationFailure()\n }\n const tag = service.hash.hmac(text, keys[1])\n if (!tag.success || !core.string.constantTimeEqual(tag.data, payload.tag))\n return transportAuthenticationFailure()\n const plaintext = service.symmetric.decryptWithIV(payload.ciphertext, keys[0], payload.iv)\n if (!plaintext.success)\n return transportAuthenticationFailure()\n const bytes = new TextEncoder().encode(plaintext.data).byteLength\n if (bytes > limits.plaintextBytes)\n return err(HaiCryptoError.TRANSPORT_PAYLOAD_TOO_LARGE, cryptoM('crypto_transportBodyTooLarge'), new TransportBodyTooLargeError(limits.plaintextBytes, bytes, { direction: payload.direction }))\n return plaintext\n }\n catch {\n return transportAuthenticationFailure()\n }\n}\n\n/**\n * 内部格式守卫,只接受v2精确字段与预算;形状合法不代表签名/MAC/时效/nonce有效。\n * @param value - 未知JSON值。\n * @returns 是否可继续执行认证校验,不能据此执行业务。\n *\n * @example 模块内部上下文\n * ```ts\n * const { crypto } = await import('@h-ai/crypto')\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const generated = crypto.asymmetric.generateKeyPair()\n * if (!generated.success) throw new Error(generated.error.message)\n * const pair = generated.data\n * const digest = crypto.hash.hash('/api/v1/orders?sort=created')\n * if (!digest.success) throw new Error(digest.error.message)\n * const context: TransportMessageContext = { version: 2, serverKeyId: 'v1', clientId: 'client-test', requestId: globalThis.crypto.randomUUID().replaceAll('-', ''), issuedAt: Date.now(), method: 'POST', pathHash: digest.data }\n * const sealed = sealTransportPayload(crypto, 'hello', context, 'request', 0, pair.publicKey, pair.privateKey)\n * if (!sealed.success) throw new Error(sealed.error.message)\n * const validShape = isValidEncryptedPayload(sealed.data)\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport function isValidEncryptedPayload(value: unknown, limits: TransportBodyLimits = TRANSPORT_BODY_LIMITS): value is EncryptedPayload {\n if (!value || typeof value !== 'object')\n return false\n const p = value as Record<string, unknown>\n const c = p.context as Partial<TransportMessageContext> | undefined\n return Object.keys(p).length === 8 && !!c && typeof c === 'object' && Object.keys(c).length === 7 && c.version === TRANSPORT_PROTOCOL.VERSION\n && typeof c.serverKeyId === 'string' && /^[\\w-]{1,64}$/.test(c.serverKeyId)\n && typeof c.clientId === 'string' && /^[\\w-]{1,128}$/.test(c.clientId)\n && typeof c.requestId === 'string' && /^[a-f0-9]{32}$/.test(c.requestId)\n && Number.isSafeInteger(c.issuedAt) && c.issuedAt! > 0\n && typeof c.method === 'string' && /^[A-Z]{1,16}$/.test(c.method)\n && typeof c.pathHash === 'string' && /^[a-f0-9]{64}$/.test(c.pathHash)\n && (p.direction === 'request' || p.direction === 'response')\n && Number.isInteger(p.status) && (p.direction === 'request' ? p.status === 0 : Number(p.status) >= 100 && Number(p.status) <= 599)\n && typeof p.encryptedKey === 'string' && /^[a-f0-9]{1,8192}$/i.test(p.encryptedKey)\n && typeof p.ciphertext === 'string' && p.ciphertext.length <= limits.encryptedPayloadBytes\n && p.ciphertext.length > 0 && p.ciphertext.length % 32 === 0 && /^[a-f0-9]+$/i.test(p.ciphertext)\n && typeof p.iv === 'string' && /^[a-f0-9]{32}$/i.test(p.iv)\n && typeof p.tag === 'string' && /^[a-f0-9]{64}$/.test(p.tag)\n && typeof p.signature === 'string' && /^[a-f0-9]{128}$/i.test(p.signature)\n}\n\n/**\n * 内部逐字段关联响应与待处理请求;上下文相同仍须验证签名、MAC和状态。\n * @param a - 响应认证上下文。\n * @param b - 本次原始请求上下文。\n * @returns 全字段是否相同,不以引用相等代替关联。\n *\n * @example 模块内部上下文\n * ```ts\n * const { crypto } = await import('@h-ai/crypto')\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const digest = crypto.hash.hash('/api/v1/orders?sort=created')\n * if (!digest.success) throw new Error(digest.error.message)\n * const context: TransportMessageContext = { version: 2, serverKeyId: 'v1', clientId: 'client-test', requestId: globalThis.crypto.randomUUID().replaceAll('-', ''), issuedAt: Date.now(), method: 'POST', pathHash: digest.data }\n * const matches = sameTransportContext(context, { ...context })\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport function sameTransportContext(a: TransportMessageContext, b: TransportMessageContext): boolean {\n return a.version === b.version && a.serverKeyId === b.serverKeyId && a.clientId === b.clientId\n && a.requestId === b.requestId && a.issuedAt === b.issuedAt && a.method === b.method && a.pathHash === b.pathHash\n}\n","/** @h-ai/crypto — serv/kit 共用的安全传输错误响应。 */\nimport type { TransportBodyTooLargeError } from './crypto-transport-body.js'\nimport type { TransportEncryptionManager, TransportMessageContext } from './crypto-transport-types.js'\nimport { cryptoM } from '../crypto-i18n.js'\nimport { HaiCryptoError } from '../crypto-types.js'\nimport { TRANSPORT_PROTOCOL } from './crypto-transport-types.js'\n\n/**\n * 已认证请求的时间窗口错误;只提供校时建议,不调整时钟或放宽防重放窗口。\n * @example\n * ```ts\n * import { TransportTimeError } from '@h-ai/crypto'\n * const error = new TransportTimeError()\n * // 展示 error.message;同步设备/服务器时间后由用户刷新重试。\n * ```\n */\nexport class TransportTimeError extends Error {\n readonly code = HaiCryptoError.TRANSPORT_TIME_INVALID.code\n\n constructor(readonly context?: TransportMessageContext) {\n super(cryptoM('crypto_transportTimeInvalid'))\n this.name = 'TransportTimeError'\n }\n}\n\n/**\n * 创建脱敏传输错误;已验证绑定、签名和 MAC 的时间/响应容量错误继续加密,请求读取超限返回 HTTP 413。\n * @param error - 容量或时间错误,不包含业务报文。\n * @param authenticated - 仅在请求绑定、签名和 MAC 已验证后提供管理器和上下文。\n * @param authenticated.manager - 使用原服务端预算的管理器。\n * @param authenticated.context - 已验证请求绑定、签名和 MAC 的上下文;时间拒绝不会放行业务。\n * @returns 可诊断的失败响应;加密失败仍只返回错误,不发送原业务响应。\n * @example\n * ```ts\n * import { createTransportErrorResponse, TransportBodyTooLargeError } from '@h-ai/crypto'\n * const response = await createTransportErrorResponse(new TransportBodyTooLargeError(1024, 1025))\n * const status = response.status // 413\n * ```\n */\nexport async function createTransportErrorResponse(\n error: TransportBodyTooLargeError | TransportTimeError,\n authenticated?: { manager: TransportEncryptionManager, context: TransportMessageContext },\n): Promise<Response> {\n const status = error instanceof TransportTimeError ? 400 : error.direction === 'request' ? 413 : 500\n const body = JSON.stringify({ success: false, error: { code: error.code, message: error.message, httpStatus: status, details: error instanceof TransportTimeError\n ? undefined\n : {\n direction: error.direction,\n stage: error.stage,\n limitBytes: error.limitBytes,\n actualBytes: error.actualBytes,\n } } })\n if (authenticated) {\n const encrypted = await authenticated.manager.encryptResponse(authenticated.context, body, status)\n if (encrypted.success) {\n return Response.json(encrypted.data, { status, headers: { [TRANSPORT_PROTOCOL.ENCRYPTED_HEADER]: TRANSPORT_PROTOCOL.ENCRYPTED_HEADER_VALUE } })\n }\n }\n return new Response(body, { status, headers: { 'Content-Type': 'application/json; charset=utf-8' } })\n}\n","/**\n * @h-ai/crypto — 传输加密客户端实现\n *\n * 提供浏览器 / Node 环境下使用的 `encryptedFetch` 包装:\n * - 首次调用前自动与服务端做一次密钥协商;\n * - 之后所有出站请求自动以混合加密包裹;\n * - 验证响应关联、发送方签名与 MAC 后解密,缺少认证的响应拒绝。\n *\n * 与服务端协议常量统一来自 {@link TRANSPORT_PROTOCOL},确保不漂移。\n *\n * @module crypto-transport-client\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type {\n EncryptedPayload,\n KeyExchangeResponse,\n TransportClient,\n TransportCryptoServiceLike,\n TransportKeyPair,\n TransportMessageContext,\n} from './crypto-transport-types.js'\nimport { err, HaiCommonError, ok } from '@h-ai/core'\nimport { cryptoM } from '../crypto-i18n.js'\nimport { HaiCryptoError } from '../crypto-types.js'\nimport { readTransportBody, resolveTransportBodyLimits, TRANSPORT_BODY_LIMITS, TransportBodyTooLargeError } from './crypto-transport-body.js'\nimport { hashTransportPath, isValidEncryptedPayload, openTransportPayload, sameTransportContext, sealTransportPayload } from './crypto-transport-codec.js'\nimport { TransportTimeError } from './crypto-transport-error.js'\nimport { TRANSPORT_PROTOCOL } from './crypto-transport-types.js'\n\n/**\n * 内部传输客户端工厂配置;模块公开入口为crypto.transport.createClient,crypto需已初始化。\n *\n * @example 模块内部上下文\n * ```ts\n * const { crypto } = await import('@h-ai/crypto')\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const options: CreateTransportClientOptions = { crypto, keyExchangeUrl: 'https://api.example.com/api/v1/_hai/key-exchange' }\n * const client = createTransportClient(options)\n * try { const ready = await client.init()\n * if (!ready.success) throw new Error(ready.error.message) }\n * finally { client.destroy() }\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport interface CreateTransportClientOptions {\n /** 可选本地明文上限;未指定时跟随服务端握手,指定时取两者较小值。 */\n maxPlaintextBytes?: number\n /** 加密能力实现(通常直接传 `crypto` 实例)。 */\n crypto: TransportCryptoServiceLike\n /** 密钥协商完整 URL,例如 `https://api.example.com/_hai/key-exchange`。 */\n keyExchangeUrl: string\n /**\n * 实际发送 HTTP 请求的 fetch 实现;默认使用全局 `fetch`。\n *\n * 可注入测试或平台桥接实现;实现必须遵守 fetch 的正文、响应与取消信号契约。\n */\n fetch?: typeof fetch\n}\n\n/**\n * 创建模块内部传输会话;同一在途协商共享Promise,首次请求前协商,后续复用。\n * 协议仅接受匹配原请求/HTTP状态的认证响应;明文、缺标记、错误签名/MAC一律拒绝。\n * @param options - 已初始化crypto、完整HTTPS协商URL和可选fetch。\n * @returns 会话;init返回HaiResult,encryptedFetch按fetch契约reject,destroy只清本地状态。\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const client = crypto.transport.createClient({ keyExchangeUrl: 'https://api.example.com/api/v1/_hai/key-exchange' })\n * try {\n * const ready = await client.init()\n * if (!ready.success) throw new Error(ready.error.message)\n * const response = await client.encryptedFetch('https://api.example.com/api/v1/orders')\n * if (!response.ok) throw new Error('HTTP request failed')\n * }\n * finally { client.destroy() }\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport function createTransportClient(options: CreateTransportClientOptions): TransportClient {\n const baseFetch = options.fetch ?? fetch\n // 显式本地配置立即校验;未配置时由可信 TLS 握手提供服务端预算。\n const localLimits = options.maxPlaintextBytes === undefined ? undefined : resolveTransportBodyLimits(options.maxPlaintextBytes)\n let bodyLimits = localLimits ?? resolveTransportBodyLimits()\n let keyPair: TransportKeyPair | null = null\n let serverPublicKey: string | null = null\n let serverKeyId: string | null = null\n let clientId: string | null = null\n /** 进行中的协商 Promise;用于并发去重。 */\n let initPromise: Promise<HaiResult<void>> | null = null\n\n /**\n * 生成本客户端密钥,30秒预算内协商并有界读取握手,只有验证响应结构后提交会话状态。\n * @returns 协商HaiResult;失败不把部分状态当ready。\n *\n * @example 模块内部上下文\n * ```ts\n * const initialized = await doInit()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * ```\n */\n async function doInit(): Promise<HaiResult<void>> {\n const kpResult = options.crypto.asymmetric.generateKeyPair()\n if (!kpResult.success)\n return err(HaiCommonError.INTERNAL_ERROR, cryptoM('crypto_transportClientKeyGenerateFailed'), kpResult.error)\n const localKeyPair = kpResult.data\n if (new TextEncoder().encode(localKeyPair.publicKey).byteLength > TRANSPORT_BODY_LIMITS.publicKeyBytes)\n return err(HaiCommonError.INTERNAL_ERROR, cryptoM('crypto_transportClientKeyGenerateFailed'))\n\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(new DOMException('Key exchange timed out', 'TimeoutError')), 30_000)\n try {\n let response: Response\n try {\n response = await baseFetch(options.keyExchangeUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ clientPublicKey: localKeyPair.publicKey }),\n signal: controller.signal,\n })\n }\n catch (cause) {\n return err(HaiCommonError.INTERNAL_ERROR, cryptoM('crypto_transportKeyExchangeRequestFailed'), cause)\n }\n\n if (!response.ok) {\n void response.body?.cancel().catch(() => {})\n return err(HaiCommonError.INTERNAL_ERROR, cryptoM('crypto_transportKeyExchangeHttpFailed', { params: { status: response.status } }))\n }\n\n let body: unknown\n try {\n body = JSON.parse(await readTransportBody(response.body, {\n maxBytes: TRANSPORT_BODY_LIMITS.keyExchangeBytes,\n signal: controller.signal,\n }))\n }\n catch {\n // JSON 解析异常可能包含响应片段,不能进入 HaiResult/cause。\n return err(HaiCommonError.INTERNAL_ERROR, cryptoM('crypto_transportKeyExchangeInvalidJson'))\n }\n if (!isKeyExchangeResponse(body)) {\n return err(HaiCommonError.INTERNAL_ERROR, cryptoM('crypto_transportKeyExchangeMissingFields'))\n }\n\n try {\n const serverLimits = resolveTransportBodyLimits(body.maxPlaintextBytes)\n bodyLimits = resolveTransportBodyLimits(Math.min(localLimits?.plaintextBytes ?? serverLimits.plaintextBytes, serverLimits.plaintextBytes))\n }\n catch {\n return err(HaiCommonError.INTERNAL_ERROR, cryptoM('crypto_transportBodyLimitInvalid'))\n }\n\n keyPair = localKeyPair\n serverPublicKey = body.serverPublicKey\n serverKeyId = body.serverKeyId\n clientId = body.clientId\n return ok(undefined)\n }\n finally {\n clearTimeout(timeout)\n }\n }\n\n /**\n * 同一会话共享在途协商Promise;失败清除Promise允许后续重试,成功复用已建立状态。\n * @returns 协商结果;单个业务请求取消只停止自己的等待,不中断其它调用的共享握手。\n *\n * @example 模块内部上下文\n * ```ts\n * const [first, second] = await Promise.all([ensureReady(), ensureReady()])\n * if (!first.success) throw new Error(first.error.message)\n * if (!second.success) throw new Error(second.error.message)\n * ```\n */\n async function ensureReady(): Promise<HaiResult<void>> {\n if (clientId && serverPublicKey)\n return ok(undefined)\n if (!initPromise) {\n initPromise = doInit().then((result) => {\n // 失败时清空 promise,允许下次重试;成功时保留即可。\n if (!result.success)\n initPromise = null\n return result\n })\n }\n return initPromise\n }\n\n /**\n * 使用已协商的服务端公钥和客户端私钥创建请求认证封装;未就绪直接失败。\n * @param plaintext - 已有界读取的原请求明文。\n * @param context - 从本次实际请求生成的绑定上下文。\n * @returns v2认证封装或失败。\n *\n * @example 模块内部上下文\n * ```ts\n * function sealActual(plaintext: string, context: TransportMessageContext) {\n * const result = encryptBody(plaintext, context)\n * if (!result.success) throw new Error(result.error.message)\n * return result.data\n * }\n * ```\n */\n function encryptBody(plaintext: string, context: TransportMessageContext): HaiResult<EncryptedPayload> {\n if (!serverPublicKey || !serverKeyId || !keyPair)\n return err(HaiCommonError.INTERNAL_ERROR, cryptoM('crypto_transportClientNotInitialized'))\n return sealTransportPayload(options.crypto, plaintext, context, 'request', 0, serverPublicKey, keyPair.privateKey, bodyLimits)\n }\n\n /**\n * 用本地私钥和协商服务端公钥验签/MAC后解密;调用前还须关联本次请求上下文和HTTP状态。\n * @param payload - 已经过形状与响应关联检查的完整封装。\n * @returns 明文或失败。\n *\n * @example 模块内部上下文\n * ```ts\n * function openActual(payload: EncryptedPayload) {\n * const result = decryptPayload(payload)\n * if (!result.success) throw new Error(result.error.message)\n * return result.data\n * }\n * ```\n */\n function decryptPayload(payload: EncryptedPayload): HaiResult<string> {\n if (!keyPair || !serverPublicKey)\n return err(HaiCommonError.INTERNAL_ERROR, cryptoM('crypto_transportClientNotInitialized'))\n return openTransportPayload(options.crypto, payload, keyPair.privateKey, serverPublicKey, bodyLimits)\n }\n\n const encryptedFetch: typeof fetch = async (input, init) => {\n const requestInput = isRequestLike(input) ? input : undefined\n const signal = init?.signal ?? requestInput?.signal ?? undefined\n signal?.throwIfAborted()\n // 密钥协商请求本身不加密,避免无限递归。\n const targetUrl = typeof input === 'string'\n ? input\n : input instanceof URL\n ? input.toString()\n : requestInput?.url ?? String(input)\n if (targetUrl === options.keyExchangeUrl)\n return baseFetch(input, init)\n\n // 单个请求取消只停止自己的等待;共享握手由独立的有界超时管理,避免取消其它调用。\n let onAbort: (() => void) | undefined\n let ready: HaiResult<void>\n try {\n ready = await (signal\n ? Promise.race([\n ensureReady(),\n new Promise<never>((_resolve, reject) => {\n onAbort = () => reject(signal.reason)\n signal.addEventListener('abort', onAbort, { once: true })\n if (signal.aborted)\n onAbort()\n }),\n ])\n : ensureReady())\n }\n finally {\n if (onAbort)\n signal?.removeEventListener('abort', onAbort)\n }\n if (!ready.success)\n throw new Error(ready.error.message)\n\n // 复制并改造 init:附加 X-Client-Id;空正文也生成认证封装。\n const headers = new Headers(init?.headers ?? requestInput?.headers)\n headers.set(TRANSPORT_PROTOCOL.CLIENT_ID_HEADER, clientId!)\n\n // 兼容 oRPC 等场景:body 可能在 Request 上而非 init.body。\n let rawBody: BodyInit | null | undefined = init?.body\n if (rawBody == null && requestInput) {\n const method = (init?.method ?? requestInput.method).toUpperCase()\n if (method !== 'GET' && method !== 'HEAD') {\n const text = await readTransportBody(requestInput.body, { maxBytes: bodyLimits.plaintextBytes, signal })\n if (text)\n rawBody = text\n }\n }\n\n const method = (init?.method ?? requestInput?.method ?? 'GET').toUpperCase()\n const base = new URL(options.keyExchangeUrl, globalThis.location?.href ?? 'http://localhost')\n const url = new URL(targetUrl, base)\n const pathHash = hashTransportPath(options.crypto, url.pathname + url.search)\n if (!pathHash.success)\n throw new Error(pathHash.error.message)\n const context: TransportMessageContext = {\n version: TRANSPORT_PROTOCOL.VERSION,\n serverKeyId: serverKeyId!,\n clientId: clientId!,\n requestId: options.crypto.symmetric.generateKey(),\n issuedAt: Date.now(),\n method,\n pathHash: pathHash.data,\n }\n const plaintext = rawBody == null ? '' : await readTransportBody(new Response(rawBody).body, { maxBytes: bodyLimits.plaintextBytes, signal })\n const encResult = encryptBody(plaintext, context)\n if (!encResult.success)\n throw new Error(encResult.error.message)\n const serialized = JSON.stringify(encResult.data)\n if (new TextEncoder().encode(serialized).byteLength > bodyLimits.encryptedPayloadBytes)\n throw new TransportBodyTooLargeError(bodyLimits.encryptedPayloadBytes, new TextEncoder().encode(serialized).byteLength, { stage: 'encrypted' })\n let nextBody: BodyInit | null | undefined\n headers.delete(TRANSPORT_PROTOCOL.ENVELOPE_HEADER)\n headers.set(TRANSPORT_PROTOCOL.ENCRYPTED_HEADER, TRANSPORT_PROTOCOL.ENCRYPTED_HEADER_VALUE)\n headers.delete('Content-Length')\n headers.delete('Content-Encoding')\n if (method === 'GET' || method === 'HEAD') {\n // Fetch 禁止 GET/HEAD 正文;仍必须认证请求,空正文封装使用有界头字段。\n if (new TextEncoder().encode(serialized).byteLength > TRANSPORT_BODY_LIMITS.envelopeHeaderBytes)\n throw new TransportBodyTooLargeError(TRANSPORT_BODY_LIMITS.envelopeHeaderBytes, new TextEncoder().encode(serialized).byteLength, { stage: 'header' })\n headers.set(TRANSPORT_PROTOCOL.ENVELOPE_HEADER, serialized)\n }\n else {\n nextBody = serialized\n headers.set('Content-Type', 'application/json')\n }\n\n // 当 input 是已带 body 的 Request 时,必须改用 URL 字符串作为 input,\n // 否则底层 fetch 会优先读取原始 Request 上的明文 body,覆盖我们的密文。\n const finalInput: RequestInfo | URL = requestInput ? requestInput.url : input\n const finalInit: RequestInit = {\n ...init,\n method,\n headers,\n body: nextBody,\n cache: init?.cache ?? requestInput?.cache,\n credentials: init?.credentials ?? requestInput?.credentials,\n integrity: init?.integrity ?? requestInput?.integrity,\n keepalive: init?.keepalive ?? requestInput?.keepalive,\n mode: init?.mode ?? requestInput?.mode,\n redirect: init?.redirect ?? requestInput?.redirect,\n referrer: init?.referrer ?? requestInput?.referrer,\n referrerPolicy: init?.referrerPolicy ?? requestInput?.referrerPolicy,\n signal: init?.signal ?? requestInput?.signal,\n }\n const response = await baseFetch(finalInput, finalInit)\n\n // 请求携带认证信息,响应同样必须验证;禁止删除标记后把明文冒充当前请求的响应。\n if (response.headers.get(TRANSPORT_PROTOCOL.ENCRYPTED_HEADER) !== TRANSPORT_PROTOCOL.ENCRYPTED_HEADER_VALUE) {\n void response.body?.cancel().catch(() => {})\n if (response.status === 503)\n throw Object.assign(new Error(cryptoM('crypto_transportBusy')), { code: HaiCryptoError.TRANSPORT_BUSY.code, httpStatus: 503 })\n if (response.status === 413)\n throw new TransportBodyTooLargeError(bodyLimits.encryptedPayloadBytes, undefined, { stage: 'encrypted' })\n throw new Error(cryptoM('crypto_transportResponseDecryptFailed'))\n }\n\n let payload: unknown\n try {\n const envelope = response.headers.get(TRANSPORT_PROTOCOL.ENVELOPE_HEADER)\n if (envelope && response.body !== null) {\n void response.body.cancel().catch(() => {})\n throw new Error(cryptoM('crypto_transportResponseDecryptFailed'))\n }\n if (envelope && new TextEncoder().encode(envelope).byteLength > TRANSPORT_BODY_LIMITS.envelopeHeaderBytes)\n throw new TransportBodyTooLargeError(TRANSPORT_BODY_LIMITS.envelopeHeaderBytes, new TextEncoder().encode(envelope).byteLength, { direction: 'response', stage: 'header' })\n payload = JSON.parse(envelope ?? await readTransportBody(response.body, { maxBytes: bodyLimits.encryptedPayloadBytes, direction: 'response', stage: 'encrypted', signal }))\n }\n catch (error) {\n if (error instanceof TransportBodyTooLargeError)\n throw error\n // 保留调用方取消语义;其它解析异常不携带可能包含明文/密文的原始响应片段。\n throw new Error(cryptoM('crypto_transportResponseDecryptFailed'), signal?.aborted ? { cause: signal.reason } : undefined)\n }\n if (!isValidEncryptedPayload(payload, bodyLimits) || payload.direction !== 'response' || payload.status !== response.status\n || !sameTransportContext(payload.context, context)) {\n throw new Error(cryptoM('crypto_transportResponseDecryptFailed'))\n }\n\n const decResult = decryptPayload(payload)\n if (!decResult.success) {\n if (decResult.error.cause instanceof TransportBodyTooLargeError)\n throw decResult.error.cause\n throw new Error(decResult.error.message)\n }\n if (new TextEncoder().encode(decResult.data).byteLength > bodyLimits.plaintextBytes)\n throw new TransportBodyTooLargeError(bodyLimits.plaintextBytes, new TextEncoder().encode(decResult.data).byteLength, { direction: 'response' })\n\n // 时间建议只来自已验签/MAC、关联当前请求的响应;明文 400 不作为可信时间诊断。\n if (response.status === 400) {\n let failure: { success?: unknown, error?: { code?: unknown } } | undefined\n try {\n failure = JSON.parse(decResult.data)\n }\n catch {}\n if (failure?.success === false && failure.error?.code === HaiCryptoError.TRANSPORT_TIME_INVALID.code)\n throw new TransportTimeError()\n }\n // 只从已验签/MAC、关联请求和状态的错误报文恢复服务端响应容量诊断。\n if (response.status === 500) {\n let failure: { success?: unknown, error?: { code?: unknown, details?: Record<string, unknown> } } | undefined\n try {\n failure = JSON.parse(decResult.data)\n }\n catch {}\n const details = failure?.error?.details\n if (failure?.success === false && failure.error?.code === 'hai:crypto:070' && details?.direction === 'response'\n && (details.stage === 'plaintext' || details.stage === 'encrypted' || details.stage === 'header')\n && typeof details.limitBytes === 'number' && Number.isSafeInteger(details.limitBytes) && details.limitBytes >= 0) {\n throw new TransportBodyTooLargeError(details.limitBytes, typeof details.actualBytes === 'number' ? details.actualBytes : undefined, { direction: 'response', stage: details.stage })\n }\n }\n\n // 透传原响应头但去掉加密标记;Content-Type 还原为下游可能期望的 JSON。\n const respHeaders = new Headers(response.headers)\n respHeaders.delete(TRANSPORT_PROTOCOL.ENCRYPTED_HEADER)\n respHeaders.delete(TRANSPORT_PROTOCOL.ENVELOPE_HEADER)\n respHeaders.delete('Content-Length')\n respHeaders.delete('Content-Encoding')\n return new Response(method === 'HEAD' || [204, 304].includes(response.status) ? null : decResult.data, {\n status: response.status,\n statusText: response.statusText,\n headers: respHeaders,\n })\n }\n\n return {\n init: ensureReady,\n encryptedFetch,\n ready: () => clientId !== null && serverPublicKey !== null,\n destroy() {\n keyPair = null\n serverPublicKey = null\n serverKeyId = null\n clientId = null\n initPromise = null\n },\n }\n}\n\n/**\n * 识别当前或跨Realm的Request形态,以保留原始method/body/signal;不执行请求。\n * @param input - fetch输入。\n * @returns 是否可按Request读取字段。\n *\n * @example 模块内部上下文\n * ```ts\n * const request = new Request('https://api.example.com/api/v1/orders')\n * const recognized = isRequestLike(request)\n * ```\n */\nfunction isRequestLike(input: RequestInfo | URL): input is Request {\n if (typeof input !== 'object' || input === null)\n return false\n\n const candidate = input as Partial<Request>\n const headers = candidate.headers as { get?: unknown } | undefined\n return typeof candidate.url === 'string'\n && typeof headers?.get === 'function'\n && typeof candidate.method === 'string'\n && typeof candidate.clone === 'function'\n}\n\n/**\n * 校验握手响应的有界结构/标识;TLS负责对端真实性,后续SM2操作仍检查公钥曲线点。\n * @param body - 未知JSON响应。\n * @returns 是否可提交当前会话所需字段。\n *\n * @example 模块内部上下文\n * ```ts\n * const valid = isKeyExchangeResponse({ clientId: '', serverKeyId: '', serverPublicKey: '' })\n * // 空字段不构成一次合法握手。\n * ```\n */\nfunction isKeyExchangeResponse(body: unknown): body is KeyExchangeResponse {\n if (!body || typeof body !== 'object')\n return false\n const fields = body as Record<string, unknown>\n return typeof fields.serverPublicKey === 'string' && fields.serverPublicKey.length > 0\n && new TextEncoder().encode(fields.serverPublicKey).byteLength <= TRANSPORT_BODY_LIMITS.publicKeyBytes\n && typeof fields.clientId === 'string' && fields.clientId.length > 0\n && typeof fields.serverKeyId === 'string' && /^[\\w-]{1,64}$/.test(fields.serverKeyId)\n}\n","/**\n * @h-ai/crypto — 服务端受管传输密钥环的安全解析。\n * @module crypto-transport-keyring\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { TransportServerKeyRing } from './crypto-transport-types.js'\nimport { err, ok } from '@h-ai/core'\nimport { cryptoM } from '../crypto-i18n.js'\nimport { HaiCryptoError } from '../crypto-types.js'\nimport { TRANSPORT_BODY_LIMITS } from './crypto-transport-body.js'\n\n/**\n * 解析服务端私有JSON或受管对象,不读取环境或初始化模块;实际密钥配对由createServer验证。\n * @param serialized - Secret Manager提供的JSON字符串或对象。\n * @returns 结构有效的密钥环或脱敏INVALID_KEY,不回显私钥/原始输入。\n *\n * @example\n * ```ts\n * import { parseTransportServerKeyRing, type TransportServerKeyRing } from '@h-ai/crypto'\n * const parsed = parseTransportServerKeyRing(process.env.HAI_CRYPTO_TRANSPORT_SERVERKEYRING)\n * if (!parsed.success) throw new Error(parsed.error.message)\n * const ring: TransportServerKeyRing = parsed.data\n * // 仅服务端使用;createServer还会校验每个版本的公私钥配对。\n * ```\n */\nexport function parseTransportServerKeyRing(serialized: unknown): HaiResult<TransportServerKeyRing> {\n try {\n const value: unknown = typeof serialized === 'string' ? JSON.parse(serialized) : serialized\n if (isTransportServerKeyRing(value))\n return ok(value)\n }\n catch {}\n return err(HaiCryptoError.INVALID_KEY, cryptoM('crypto_transportServerKeyRingInvalid'))\n}\n\n/**\n * 内部结构守卫,限制版本ID、公钥/私钥文本长度,不把配置值带入错误。\n * @param value - 未知Secret解析结果。\n * @returns 是否满足密钥环结构;真实密钥配对仍由服务端工厂校验。\n *\n * @example 模块内部上下文\n * ```ts\n * const valid = isTransportServerKeyRing({ activeKeyId: 'v1', keys: {} })\n * // 缺少活动版本的密钥对,结构校验返回false。\n * ```\n */\nfunction isTransportServerKeyRing(value: unknown): value is TransportServerKeyRing {\n if (!value || typeof value !== 'object')\n return false\n const ring = value as Record<string, unknown>\n if (typeof ring.activeKeyId !== 'string' || !/^[\\w-]{1,64}$/.test(ring.activeKeyId)\n || !ring.keys || typeof ring.keys !== 'object' || Array.isArray(ring.keys)) {\n return false\n }\n if (!Object.hasOwn(ring.keys, ring.activeKeyId))\n return false\n return Object.entries(ring.keys).every(([id, pair]) => {\n if (!/^[\\w-]{1,64}$/.test(id) || !pair || typeof pair !== 'object')\n return false\n const fields = pair as Record<string, unknown>\n return typeof fields.publicKey === 'string' && fields.publicKey.length > 0\n && new TextEncoder().encode(fields.publicKey).byteLength <= TRANSPORT_BODY_LIMITS.publicKeyBytes\n && typeof fields.privateKey === 'string' && fields.privateKey.length > 0\n && fields.privateKey.length <= TRANSPORT_BODY_LIMITS.publicKeyBytes\n })\n}\n","/**\n * @h-ai/crypto — 传输加密服务端实现\n *\n * 提供服务端传输加密管理器工厂。\n *\n * @module crypto-transport-server\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type {\n TransportCreateServerOptions,\n TransportCryptoServiceLike,\n TransportEncryptionManager,\n TransportKeyPair,\n} from './crypto-transport-types.js'\nimport { core, err, HaiCommonError, ok } from '@h-ai/core'\nimport { cryptoM } from '../crypto-i18n.js'\nimport { isValidSM2PublicKey } from '../crypto-public-key.js'\nimport { HaiCryptoError } from '../crypto-types.js'\nimport { resolveTransportBodyLimits } from './crypto-transport-body.js'\nimport { hashTransportPath, isValidEncryptedPayload, openTransportPayload, sealTransportPayload, transportAuthenticationFailure } from './crypto-transport-codec.js'\nimport { TransportTimeError } from './crypto-transport-error.js'\nimport { parseTransportServerKeyRing } from './crypto-transport-keyring.js'\nimport { TRANSPORT_PROTOCOL } from './crypto-transport-types.js'\n\n/**\n * 内部服务端工厂;创建时校验并捕获受管密钥环快照,不随机回退生成服务端密钥。\n * 生产要求共享registry;先认证实际HTTP绑定/签名/MAC/nonce,再交给业务,响应关联原上下文与实际状态。\n * @param cryptoService - 已初始化SM2/SM3/SM4能力。\n * @param options - 必填受管密钥环和客户端registry。\n * @returns 管理器或脱敏HaiResult失败;应用持有底层cache/reldb并负责关闭。\n *\n * @example\n * ```ts\n * import { crypto, createRedisTransportKeyStore, parseTransportServerKeyRing } from '@h-ai/crypto'\n * import { cache } from '@h-ai/cache'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const connected = await cache.init({ type: 'redis', host: 'cache', port: 6379, password: process.env.HAI_CACHE_PASSWORD })\n * if (!connected.success) throw new Error(connected.error.message)\n * try {\n * const registry = createRedisTransportKeyStore({ cache, ttlSeconds: 3600 })\n * const ring = parseTransportServerKeyRing(process.env.HAI_CRYPTO_TRANSPORT_SERVERKEYRING)\n * if (!ring.success) throw new Error(ring.error.message)\n * const created = crypto.transport.createServer({ serverKeyRing: ring.data, keyStore: registry })\n * if (!created.success) throw new Error(created.error.message)\n * const manager = created.data\n * try {\n * const activeKeyId = manager.getServerKeyId()\n * }\n * finally { await manager.close() }\n * }\n * finally { await cache.close() }\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport function createTransportEncryption(\n cryptoService: TransportCryptoServiceLike,\n options: TransportCreateServerOptions,\n): HaiResult<TransportEncryptionManager> {\n let bodyLimits\n try {\n bodyLimits = resolveTransportBodyLimits(options?.maxPlaintextBytes)\n }\n catch {\n return err(HaiCryptoError.INVALID_INPUT, cryptoM('crypto_transportBodyLimitInvalid'))\n }\n const ring = parseTransportServerKeyRing(options?.serverKeyRing)\n if (!ring.success)\n return ring\n if (!options.keyStore || typeof options.keyStore.register !== 'function' || typeof options.keyStore.get !== 'function'\n || typeof options.keyStore.claimRequest !== 'function') {\n return err(HaiCryptoError.INVALID_INPUT, cryptoM('crypto_transportKeyStoreRequired'))\n }\n // eslint-disable-next-line node/prefer-global/process -- 此文件也随客户端打包,避免静态引入Node内建模块。\n if (core.module.requiresSharedState(globalThis.process?.env ?? {}) && options.keyStore.stateScope !== 'shared')\n return err(HaiCryptoError.INVALID_INPUT, cryptoM('crypto_transportKeyStoreRequired'))\n const serverKeys = new Map<string, TransportKeyPair>()\n for (const [id, key] of Object.entries(ring.data.keys)) {\n // 同时验证密钥格式和公私钥配对;只返回无敏感上下文的配置错误。\n const probe = cryptoService.asymmetric.encrypt('hai-transport-key-check', key.publicKey)\n if (!probe.success)\n return err(HaiCryptoError.INVALID_KEY, cryptoM('crypto_transportServerKeyRingInvalid'))\n const checked = cryptoService.asymmetric.decrypt(probe.data, key.privateKey)\n if (!checked.success || checked.data !== 'hai-transport-key-check')\n return err(HaiCryptoError.INVALID_KEY, cryptoM('crypto_transportServerKeyRingInvalid'))\n serverKeys.set(id, { publicKey: key.publicKey, privateKey: key.privateKey })\n }\n // 捕获不可变快照;调用方修改原对象不能悄悄轮换或更换同一 ID 对应的私钥。\n const activeKeyId = ring.data.activeKeyId\n const serverKeyPair = serverKeys.get(activeKeyId)!\n const keyStore = options.keyStore\n\n const manager: TransportEncryptionManager = {\n bodyLimits,\n getServerKeyId() {\n return activeKeyId\n },\n getServerPublicKey() {\n return serverKeyPair.publicKey\n },\n\n async registerClientKey(clientPublicKey) {\n if (!isValidSM2PublicKey(clientPublicKey))\n throw new TypeError(cryptoM('crypto_sm2PublicKeyInvalid'))\n return keyStore.register(clientPublicKey)\n },\n\n async getClientPublicKey(clientId) {\n return keyStore.get(clientId)\n },\n\n async encryptResponse(request, data, status) {\n try {\n const context = { ...request }\n const clientPublicKey = await keyStore.get(context.clientId)\n if (!clientPublicKey)\n return err(HaiCommonError.NOT_FOUND, cryptoM('crypto_transportClientNotRegistered'))\n const key = serverKeys.get(context.serverKeyId)\n if (!key)\n return transportAuthenticationFailure()\n return sealTransportPayload(cryptoService, data, context, 'response', status, clientPublicKey, key.privateKey, bodyLimits)\n }\n catch {\n // registry/注入实现故障仍按 HaiResult 返回,不携带可能包含连接凭据的原始异常。\n return err(HaiCommonError.INTERNAL_ERROR, cryptoM('crypto_transportResponseEncryptFailed'))\n }\n },\n\n async decryptRequest(payload, expected) {\n try {\n if (!isValidEncryptedPayload(payload, bodyLimits) || payload.direction !== 'request' || payload.status !== 0)\n return transportAuthenticationFailure()\n // 在任何异步 registry 调用前捕获快照,避免调用方修改同一对象造成认证/消费上下文错位。\n const authenticated = { ...payload, context: { ...payload.context } }\n const c = authenticated.context\n const pathHash = hashTransportPath(cryptoService, expected.path)\n if (!pathHash.success || c.clientId !== expected.clientId || c.method !== expected.method || c.pathHash !== pathHash.data) {\n return transportAuthenticationFailure()\n }\n const key = serverKeys.get(c.serverKeyId)\n const clientPublicKey = await keyStore.get(c.clientId)\n if (!key || !clientPublicKey)\n return transportAuthenticationFailure()\n const plaintext = openTransportPayload(cryptoService, authenticated, key.privateKey, clientPublicKey, bodyLimits)\n if (!plaintext.success)\n return plaintext\n const timeFailure = () => {\n const error = new TransportTimeError(c)\n return err(HaiCryptoError.TRANSPORT_TIME_INVALID, error.message, error)\n }\n // 只有请求绑定、签名和 MAC 可信后才区分时间错误,不能把篡改报文误报为时钟问题。\n const now = Date.now()\n if (c.issuedAt > now + TRANSPORT_PROTOCOL.CLOCK_SKEW_MS || now >= c.issuedAt + TRANSPORT_PROTOCOL.REQUEST_WINDOW_MS)\n return timeFailure()\n // 只有完整认证成功后才占用 nonce;原子 claim 失败或存储故障均不向业务返回明文。\n if (!await keyStore.claimRequest(c.clientId, c.requestId, c.issuedAt + TRANSPORT_PROTOCOL.REQUEST_WINDOW_MS + 2 * TRANSPORT_PROTOCOL.CLOCK_SKEW_MS)) {\n return transportAuthenticationFailure()\n }\n if (Date.now() >= c.issuedAt + TRANSPORT_PROTOCOL.REQUEST_WINDOW_MS)\n return timeFailure()\n return plaintext\n }\n catch {\n return transportAuthenticationFailure()\n }\n },\n\n async close() {\n await keyStore.close?.()\n },\n }\n\n return ok(manager)\n}\n","/**\n * @h-ai/crypto — 加密服务主入口\n *\n * 提供统一的 `crypto` 对象,聚合所有结构化加密操作。\n * @module crypto-main\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { AsymmetricOperations, CryptoFunctions, HashOperations, PasswordOperations, SymmetricOperations, TransportOperations } from './crypto-types.js'\n\nimport { core, err, ok } from '@h-ai/core'\n\nimport { cryptoM } from './crypto-i18n.js'\nimport { createPasswordFunctions } from './crypto-password.js'\nimport { createSM2 } from './crypto-sm2.js'\nimport { createSM3 } from './crypto-sm3.js'\nimport { createSM4 } from './crypto-sm4.js'\nimport {\n\n HaiCryptoError,\n\n} from './crypto-types.js'\nimport { createTransportClient } from './transport/crypto-transport-client.js'\nimport { createTransportEncryption } from './transport/crypto-transport-server.js'\nimport { TRANSPORT_PROTOCOL } from './transport/crypto-transport-types.js'\n\nconst logger = core.logger.child({ module: 'crypto', scope: 'main' })\n\n// ─── 内部状态 ───\n\n/** 是否已初始化 */\nlet initialized = false\n/** 并发初始化防护标志 */\nlet initInProgress = false\n/** 当前非对称加密操作实例 */\nlet currentAsymmetric: AsymmetricOperations | null = null\n/** 当前哈希操作实例 */\nlet currentHash: HashOperations | null = null\n/** 当前对称加密操作实例 */\nlet currentSymmetric: SymmetricOperations | null = null\n/** 当前密码哈希操作实例 */\nlet currentPassword: PasswordOperations | null = null\n\n// ─── 未初始化占位 ───\n\nconst notInitialized = core.module.createNotInitializedKit(\n HaiCryptoError.NOT_INITIALIZED,\n () => cryptoM('crypto_notInitialized'),\n)\n\nconst notInitializedAsymmetric = notInitialized.proxy<AsymmetricOperations>('sync')\nconst notInitializedHash = notInitialized.proxy<HashOperations>('sync')\nconst notInitializedSymmetric = notInitialized.proxy<SymmetricOperations>('sync')\nconst notInitializedPassword = notInitialized.proxy<PasswordOperations>('sync')\n\n// ─── 传输加密 ───\n// 直接复用顶层 crypto;服务端工厂先检查初始化,不为传输另建单例。\n\n// 通过函数声明(hoisted)延迟引用 `crypto`,避免 use-before-define 报错;\n// 实际调用发生在 init 之后,闭包持有的引用是安全的。\nfunction getCrypto(): CryptoFunctions {\n // eslint-disable-next-line ts/no-use-before-define\n return crypto\n}\nconst transportOperations: TransportOperations = {\n createServer: options => getCrypto().isInitialized ? createTransportEncryption(getCrypto(), options) : notInitialized.result(),\n createClient: options => createTransportClient({ crypto: getCrypto(), ...options }),\n protocol: TRANSPORT_PROTOCOL,\n}\n\n// ─── 服务对象 ───\n\n/**\n * 加密模块公开服务对象;先检查 init 的 HaiResult,再使用各操作域,最后 close。\n * SM2/SM3/SM4 原语不等于认证传输;HTTP 使用 transport 的签名、MAC、上下文和共享 nonce 校验。\n *\n * @example\n * ```ts\n * import { crypto } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const generated = crypto.asymmetric.generateKeyPair()\n * if (!generated.success) throw new Error(generated.error.message)\n * const pair = generated.data\n * const digest = crypto.hash.hash('hello')\n * if (!digest.success) throw new Error(digest.error.message)\n * const publicKeyValid = crypto.asymmetric.isValidPublicKey(pair.publicKey)\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport const crypto: CryptoFunctions = {\n /**\n * 初始化加密模块\n *\n * 创建非对称/哈希/对称/密码哈希操作实例。\n * 重复调用会先关闭再重新初始化。\n *\n * @returns 成功时返回 ok(undefined);失败时返回 INIT_FAILED\n */\n async init(): Promise<HaiResult<void>> {\n // 并发初始化防护:避免多次 init 同时执行导致资源泄漏\n if (initInProgress) {\n logger.warn('Crypto init already in progress, skipping concurrent call')\n return err(\n HaiCryptoError.INIT_FAILED,\n cryptoM('crypto_initFailed', { params: { error: 'Concurrent initialization detected' } }),\n )\n }\n initInProgress = true\n\n try {\n // 让并发调用有机会观察到 initInProgress,确保防护逻辑真实生效。\n await Promise.resolve()\n\n if (initialized) {\n logger.warn('Crypto module is already initialized, reinitializing')\n await crypto.close()\n }\n\n logger.info('Initializing crypto module')\n\n currentAsymmetric = createSM2()\n currentHash = createSM3()\n currentSymmetric = createSM4()\n currentPassword = createPasswordFunctions({ hash: currentHash })\n initialized = true\n logger.info('Crypto module initialized')\n return ok(undefined)\n }\n catch (error) {\n // 清理部分赋值的状态\n currentAsymmetric = null\n currentHash = null\n currentSymmetric = null\n currentPassword = null\n initialized = false\n logger.error('Crypto module initialization failed', { error })\n return err(\n HaiCryptoError.INIT_FAILED,\n cryptoM('crypto_initFailed', {\n params: { error: error instanceof Error ? error.message : String(error) },\n }),\n error,\n )\n }\n finally {\n initInProgress = false\n }\n },\n\n /** 非对称加密操作(未初始化时所有方法返回 NOT_INITIALIZED) */\n get asymmetric(): AsymmetricOperations { return currentAsymmetric ?? notInitializedAsymmetric },\n /** 哈希操作(未初始化时所有方法返回 NOT_INITIALIZED) */\n get hash(): HashOperations { return currentHash ?? notInitializedHash },\n /** 对称加密操作(未初始化时所有方法返回 NOT_INITIALIZED) */\n get symmetric(): SymmetricOperations { return currentSymmetric ?? notInitializedSymmetric },\n /** 密码哈希操作(未初始化时所有方法返回 NOT_INITIALIZED) */\n get password(): PasswordOperations { return currentPassword ?? notInitializedPassword },\n /**\n * 传输加密操作(端到端混合加密)\n *\n * createServer 检查初始化后复用 asymmetric/symmetric;未初始化返回 NOT_INITIALIZED。\n */\n transport: transportOperations,\n /** 是否已初始化 */\n get isInitialized() { return initialized },\n\n /**\n * 关闭加密模块,释放内部状态\n *\n * 关闭后访问 asymmetric/hash/symmetric/password 会返回 NOT_INITIALIZED 错误。\n */\n async close() {\n if (!initialized) {\n logger.info('Crypto module already closed, skipping')\n return\n }\n\n logger.info('Closing crypto module')\n\n currentAsymmetric = null\n currentHash = null\n currentSymmetric = null\n currentPassword = null\n initialized = false\n\n logger.info('Crypto module closed')\n },\n}\n","import type { HaiResult } from '@h-ai/core'\n/**\n * @h-ai/crypto — serv/kit 共用的实际 HTTP 请求认证入口。\n * @module crypto-transport-request\n */\nimport type { TransportBodyLimits } from './crypto-transport-body.js'\nimport type { EncryptedRequestPayload, TransportEncryptionManager, TransportMessageContext } from './crypto-transport-types.js'\nimport { ok } from '@h-ai/core'\nimport { readTransportBody, TRANSPORT_BODY_LIMITS, TransportBodyTooLargeError } from './crypto-transport-body.js'\nimport { isValidEncryptedPayload, transportAuthenticationFailure } from './crypto-transport-codec.js'\nimport { TRANSPORT_PROTOCOL } from './crypto-transport-types.js'\n\n/**\n * 从实际HTTP请求提取可信方法/路径/查询/客户端ID并有界认证;成功后才执行业务。\n * 拒绝缺少认证及头/正文重复承载,空请求也认证;不会由payload自证HTTP上下文。\n * @param manager - 使用共享原子nonce registry的已创建管理器。\n * @param request - 未消费正文的真实Request。\n * @param limits - HTTP 路由容量;默认管理器协商容量。\n * @returns 明文和响应关联上下文;认证失败无明文。\n * @throws RangeError超限;流读取/取消沿用原异常,HTTP适配器负责转响应。\n *\n * @example\n * ```ts\n * import { authenticateTransportRequest, TRANSPORT_PROTOCOL, type TransportEncryptionManager } from '@h-ai/crypto'\n * async function handle(manager: TransportEncryptionManager, request: Request): Promise<Response> {\n * const verified = await authenticateTransportRequest(manager, request)\n * if (!verified.success) return new Response(null, { status: 400 })\n * const encrypted = await manager.encryptResponse(verified.data.context, JSON.stringify({ accepted: true }), 200)\n * if (!encrypted.success) return new Response(null, { status: 500 })\n * return Response.json(encrypted.data, { headers: { [TRANSPORT_PROTOCOL.ENCRYPTED_HEADER]: TRANSPORT_PROTOCOL.ENCRYPTED_HEADER_VALUE } })\n * }\n * ```\n */\nexport async function authenticateTransportRequest(\n manager: TransportEncryptionManager,\n request: Request,\n limits: TransportBodyLimits = manager.bodyLimits,\n): Promise<HaiResult<{ plaintext: string, context: TransportMessageContext }>> {\n const reject = () => {\n void request.body?.cancel().catch(() => {})\n return transportAuthenticationFailure()\n }\n if (request.headers.get(TRANSPORT_PROTOCOL.ENCRYPTED_HEADER) !== TRANSPORT_PROTOCOL.ENCRYPTED_HEADER_VALUE)\n return reject()\n const clientId = request.headers.get(TRANSPORT_PROTOCOL.CLIENT_ID_HEADER)\n if (!clientId)\n return reject()\n const envelope = request.headers.get(TRANSPORT_PROTOCOL.ENVELOPE_HEADER)\n const bodyless = request.method === 'GET' || request.method === 'HEAD'\n if ((bodyless && (!envelope || request.body !== null)) || (!bodyless && envelope !== null))\n return reject()\n if (envelope && new TextEncoder().encode(envelope).byteLength > TRANSPORT_BODY_LIMITS.envelopeHeaderBytes)\n throw new TransportBodyTooLargeError(TRANSPORT_BODY_LIMITS.envelopeHeaderBytes, new TextEncoder().encode(envelope).byteLength, { stage: 'header' })\n const text = envelope ?? await readTransportBody(request.body, {\n maxBytes: limits.encryptedPayloadBytes,\n stage: 'encrypted',\n signal: request.signal,\n })\n let payload: unknown\n try {\n payload = JSON.parse(text)\n }\n catch {\n return transportAuthenticationFailure()\n }\n if (!isValidEncryptedPayload(payload, limits) || payload.direction !== 'request' || payload.status !== 0)\n return transportAuthenticationFailure()\n const url = new URL(request.url)\n const decrypted = await manager.decryptRequest(payload as EncryptedRequestPayload, {\n clientId,\n method: request.method,\n path: url.pathname + url.search,\n })\n if (!decrypted.success) {\n if (decrypted.error.cause instanceof TransportBodyTooLargeError)\n throw decrypted.error.cause\n return decrypted\n }\n if (new TextEncoder().encode(decrypted.data).byteLength > limits.plaintextBytes)\n throw new TransportBodyTooLargeError(limits.plaintextBytes, new TextEncoder().encode(decrypted.data).byteLength)\n if (bodyless && decrypted.data !== '')\n return transportAuthenticationFailure()\n return ok({ plaintext: decrypted.data, context: payload.context })\n}\n","/**\n * @h-ai/crypto — 传输加密内存 key store\n *\n * 提供显式开发/测试使用的进程内客户端公钥存储,生产使用共享 registry。\n * @module crypto-transport-store-memory\n */\n\nimport type { TransportKeyStore } from '../crypto-transport-types.js'\nimport { cryptoM } from '../../crypto-i18n.js'\nimport { isValidSM2PublicKey } from '../../crypto-public-key.js'\n\nconst DEFAULT_MAX_CLIENTS = 10000\n\nfunction normalizeMaxClients(maxClients: number): number {\n if (!Number.isFinite(maxClients))\n return DEFAULT_MAX_CLIENTS\n return Math.max(1, Math.floor(maxClients))\n}\n\nfunction createClientId(counter: number): string {\n const entropy = typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function'\n ? crypto.randomUUID().replace(/-/g, '')\n : Math.random().toString(36).slice(2, 12)\n\n return `c_${counter}_${Date.now()}_${entropy}`\n}\n\n/**\n * 显式创建开发/测试用进程内FIFO公钥registry;不跨进程、不持久化,生产共享状态守卫拒绝它。\n * 有效nonce不会因公钥FIFO容量而提前逐出;过期nonce惰性清理。\n * @param maxClients - 公钥容量,默认10000,超限淘汰最早公钥。\n * @returns 本地registry;无效SM2公钥拒绝Promise。\n *\n * @example\n * ```ts\n * import { crypto, createInMemoryKeyStore } from '@h-ai/crypto'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const generated = crypto.asymmetric.generateKeyPair()\n * if (!generated.success) throw new Error(generated.error.message)\n * const pair = generated.data\n * const registry = createInMemoryKeyStore(100)\n * const clientId = await registry.register(pair.publicKey)\n * const saved = await registry.get(clientId)\n * await registry.delete?.(clientId)\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport function createInMemoryKeyStore(maxClients = DEFAULT_MAX_CLIENTS): TransportKeyStore {\n const clientKeys = new Map<string, string>()\n const requests = new Map<string, number>()\n const capacity = normalizeMaxClients(maxClients)\n let counter = 0\n\n return {\n get stateScope(): 'local' { return 'local' },\n async register(publicKey) {\n if (!isValidSM2PublicKey(publicKey))\n throw new TypeError(cryptoM('crypto_sm2PublicKeyInvalid'))\n counter++\n const clientId = createClientId(counter)\n\n if (clientKeys.size >= capacity) {\n const oldest = clientKeys.keys().next().value\n if (oldest !== undefined)\n clientKeys.delete(oldest)\n }\n\n clientKeys.set(clientId, publicKey)\n return clientId\n },\n\n async get(clientId) {\n return clientKeys.get(clientId)\n },\n\n async claimRequest(clientId, requestId, expiresAt) {\n const now = Date.now()\n for (const [id, expiry] of requests) {\n if (expiry <= now)\n requests.delete(id)\n }\n const id = JSON.stringify([clientId, requestId])\n if (requests.has(id) || expiresAt <= now)\n return false\n // 开发/测试单进程内同步 check + set,不在两步之间 await;有效 nonce 不得按容量驱逐。\n requests.set(id, expiresAt)\n return true\n },\n\n async delete(clientId) {\n clientKeys.delete(clientId)\n },\n\n async close() {\n clientKeys.clear()\n requests.clear()\n },\n }\n}\n","/**\n * @h-ai/crypto — 传输加密 Redis key store\n *\n * 通过 `@h-ai/cache` 持久化客户端公钥;通常应传入已初始化为 Redis 的 `cache` 实例。\n * @module crypto-transport-store-redis\n */\n\nimport type { CacheFunctions } from '@h-ai/cache'\nimport type { HaiError, HaiResult } from '@h-ai/core'\nimport type { TransportKeyStore } from '../crypto-transport-types.js'\nimport { cryptoM } from '../../crypto-i18n.js'\nimport { isValidSM2PublicKey } from '../../crypto-public-key.js'\n\nconst TRANSPORT_KEY_CACHE_PREFIX = 'hai:crypto:transport:client'\n\n/**\n * 借用已初始化cache的registry配置;只有Redis provider报告shared,内存cache不能满足生产。\n * TTL是客户端公钥寿命,nonce另按认证窗口持有;连接由应用关闭。\n *\n * @example\n * ```ts\n * import { crypto, createRedisTransportKeyStore, parseTransportServerKeyRing } from '@h-ai/crypto'\n * import { cache } from '@h-ai/cache'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const connected = await cache.init({ type: 'redis', host: 'cache', port: 6379, password: process.env.HAI_CACHE_PASSWORD })\n * if (!connected.success) throw new Error(connected.error.message)\n * try {\n * const registry = createRedisTransportKeyStore({ cache, ttlSeconds: 3600 })\n * const options: import('@h-ai/crypto').CreateRedisTransportKeyStoreOptions = { cache, ttlSeconds: 3600 }\n * const secondView = createRedisTransportKeyStore(options)\n * const scope = secondView.stateScope\n * }\n * finally { await cache.close() }\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport interface CreateRedisTransportKeyStoreOptions {\n /** 已初始化的 `@h-ai/cache` 实例;生产环境通常应使用 Redis provider。 */\n readonly cache: CacheFunctions\n /** 客户端公钥的 TTL(正整数秒,最大 2147483647);未传则保持不过期。 */\n readonly ttlSeconds?: number\n}\n\nfunction normalizeTtlSeconds(ttlSeconds: number | undefined): number | undefined {\n if (ttlSeconds === undefined)\n return undefined\n if (!Number.isSafeInteger(ttlSeconds) || ttlSeconds <= 0 || ttlSeconds > 2_147_483_647)\n throw new TypeError(cryptoM('crypto_transportKeyStoreTtlInvalid'))\n return ttlSeconds\n}\n\nfunction createClientId(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function')\n return `c_${crypto.randomUUID()}`\n\n return `c_${Date.now()}_${Math.random().toString(36).slice(2, 12)}`\n}\n\nfunction toOperationError(operation: string, error: HaiError): Error {\n const wrapped = new Error(`${operation} failed: ${error.message}`, { cause: error }) as Error & { code?: string | number }\n wrapped.code = error.code\n return wrapped\n}\n\nfunction unwrapResult<T>(operation: string, result: HaiResult<T>): T {\n if (result.success)\n return result.data\n throw toOperationError(operation, result.error)\n}\n\n/**\n * 创建借用cache的公钥/nonce registry;生产必须Redis共享provider,nonce用单key原子CAS。\n * 公钥TTL省略则不过期,nonce有效期间禁止驱逐;容量由Redis部署预算管理,不提供DB maxClients。\n * @param options - 已初始化cache与可选正整数TTL秒,最大2147483647。\n * @returns registry;非法TTL同步TypeError,读写/公钥错误拒绝Promise,不关闭cache。\n *\n * @example\n * ```ts\n * import { crypto, createRedisTransportKeyStore, parseTransportServerKeyRing } from '@h-ai/crypto'\n * import { cache } from '@h-ai/cache'\n * const initialized = await crypto.init()\n * if (!initialized.success) throw new Error(initialized.error.message)\n * try {\n * const connected = await cache.init({ type: 'redis', host: 'cache', port: 6379, password: process.env.HAI_CACHE_PASSWORD })\n * if (!connected.success) throw new Error(connected.error.message)\n * try {\n * const registry = createRedisTransportKeyStore({ cache, ttlSeconds: 3600 })\n * const scope = registry.stateScope\n * }\n * finally { await cache.close() }\n * }\n * finally { await crypto.close() }\n * ```\n */\nexport function createRedisTransportKeyStore(options: CreateRedisTransportKeyStoreOptions): TransportKeyStore {\n const ttlSeconds = normalizeTtlSeconds(options.ttlSeconds)\n\n function buildCacheKey(clientId: string): string {\n return `${TRANSPORT_KEY_CACHE_PREFIX}:${clientId}`\n }\n\n return {\n get stateScope() { return options.cache.config?.type === 'redis' ? 'shared' : 'local' },\n async register(publicKey) {\n if (!isValidSM2PublicKey(publicKey))\n throw new TypeError(cryptoM('crypto_sm2PublicKeyInvalid'))\n const clientId = createClientId()\n const applied = unwrapResult(\n 'cache.kv.set',\n await options.cache.kv.set(\n buildCacheKey(clientId),\n publicKey,\n ttlSeconds === undefined ? undefined : { ex: ttlSeconds },\n ),\n )\n if (!applied)\n throw new Error(cryptoM('crypto_transportClientNotRegistered'))\n return clientId\n },\n\n async get(clientId) {\n const publicKey = unwrapResult(\n 'cache.kv.get',\n await options.cache.kv.get<string>(buildCacheKey(clientId)),\n )\n return publicKey ?? undefined\n },\n\n async claimRequest(clientId, requestId, expiresAt) {\n const ttl = expiresAt - Date.now()\n if (ttl <= 0)\n return false\n // 单 key 原子 CAS 在 Redis Cluster 中也只涉及一个 slot;生产禁止提前驱逐有效 nonce。\n return unwrapResult('cache.kv.compareAndSwap', await options.cache.kv.compareAndSwap(\n `hai:crypto:transport:request:${clientId}:${requestId}`,\n undefined,\n true,\n { px: ttl },\n ))\n },\n\n async delete(clientId) {\n unwrapResult('cache.kv.del', await options.cache.kv.del(buildCacheKey(clientId)))\n },\n }\n}\n","/**\n * @h-ai/crypto — 传输加密关系数据库 key store\n *\n * 通过 `@h-ai/reldb` 保存客户端公钥,适用于需要跨节点共享状态的服务端部署。\n * @module crypto-transport-store-reldb\n */\n\nimport type { HaiError, HaiResult } from '@h-ai/core'\nimport type { DmlWithTxOperations, ReldbFunctions } from '@h-ai/reldb'\nimport type { TransportKeyStore } from '../crypto-transport-types.js'\nimport { cryptoM } from '../../crypto-i18n.js'\nimport { isValidSM2PublicKey } from '../../crypto-public-key.js'\n\nconst TRANSPORT_KEY_TABLE = 'hai_crypto_transport_client_keys'\nconst TRANSPORT_REQUEST_TABLE = 'hai_crypto_transport_requests'\nconst TRANSPORT_CAPACITY_TABLE = 'hai_crypto_transport_capacity'\nconst PRUNE_BATCH_SIZE = 100\n\n/**\n * 借用已初始化数据库的registry配置;TTL与共享maxClients各节点必须一致。\n * 生产使用PostgreSQL/MySQL,DB时钟维护期限;连接由应用关闭。\n *\n * @example\n * ```ts\n * import { createReldbTransportKeyStore } from '@h-ai/crypto'\n * import { reldb } from '@h-ai/reldb'\n * const connected = await reldb.init({ type: 'postgresql', host: 'db', port: 5432, database: 'hai', user: 'postgres', password: process.env.HAI_DB_PASSWORD })\n * if (!connected.success) throw new Error(connected.error.message)\n * try {\n * const registry = createReldbTransportKeyStore({ reldb, ttlSeconds: 3600, maxClients: 10000 })\n * const options: import('@h-ai/crypto').CreateReldbTransportKeyStoreOptions = { reldb, ttlSeconds: 3600, maxClients: 10000 }\n * const secondView = createReldbTransportKeyStore(options)\n * const removed = await secondView.pruneExpired()\n * }\n * finally { await reldb.close() }\n * ```\n */\nexport interface CreateReldbTransportKeyStoreOptions {\n /** 已初始化的 `@h-ai/reldb` 实例。 */\n readonly reldb: ReldbFunctions\n /** 公钥 TTL,正整数秒且最大 2147483647;省略则不过期。 */\n readonly ttlSeconds?: number\n /** 所有节点共享的有效公钥容量,正安全整数,默认 10000;各节点必须一致。 */\n readonly maxClients?: number\n}\n\n/**\n * 数据库registry及有界过期维护;注册自动维护,无流量时应用应定期调度pruneExpired。\n * 不淘汰有效公钥/nonce,不创建后台计时器;维护失败拒绝并可重试。\n *\n * @example\n * ```ts\n * import { createReldbTransportKeyStore } from '@h-ai/crypto'\n * import { reldb } from '@h-ai/reldb'\n * const connected = await reldb.init({ type: 'postgresql', host: 'db', port: 5432, database: 'hai', user: 'postgres', password: process.env.HAI_DB_PASSWORD })\n * if (!connected.success) throw new Error(connected.error.message)\n * try {\n * const registry = createReldbTransportKeyStore({ reldb, ttlSeconds: 3600, maxClients: 10000 })\n * const removed = await registry.pruneExpired()\n * }\n * finally { await reldb.close() }\n * ```\n */\nexport interface ReldbTransportKeyStore extends TransportKeyStore {\n /**\n * 按数据库时钟最多删除 100 条过期公钥和 100 条过期 nonce,返回实际删除总数。\n * 不驱逐有效记录;建表或维护故障会 reject,之后允许重新调用。应用可以定期调度本方法。\n * @returns 异步操作结果;存储或网络故障按方法契约拒绝。\n *\n * @example\n * ```ts\n * import { createReldbTransportKeyStore } from '@h-ai/crypto'\n * import { reldb } from '@h-ai/reldb'\n * const connected = await reldb.init({ type: 'postgresql', host: 'db', port: 5432, database: 'hai', user: 'postgres', password: process.env.HAI_DB_PASSWORD })\n * if (!connected.success) throw new Error(connected.error.message)\n * try {\n * const registry = createReldbTransportKeyStore({ reldb, ttlSeconds: 3600, maxClients: 10000 })\n * const removed = await registry.pruneExpired()\n * }\n * finally { await reldb.close() }\n * ```\n */\n pruneExpired: () => Promise<number>\n}\n\nfunction toOperationError(operation: string, error: HaiError): Error {\n // 不把驱动错误、连接串或公钥附加到可被 HTTP 适配器记录的异常。\n return Object.assign(new Error(cryptoM('crypto_transportKeyStoreOperationFailed')), { operation, code: error.code })\n}\n\nfunction unwrapResult<T>(operation: string, result: HaiResult<T>): T {\n if (result.success)\n return result.data\n throw toOperationError(operation, result.error)\n}\n\n/**\n * 创建共享数据库registry;首次操作惰性建表,失败可重试,事务锁住持久容量行后注册。\n * 每次注册有界维护;公钥TTL与过期维护使用数据库epoch毫秒,传输窗口仍要求节点时钟同步,不能提前删除有效nonce。\n * @param options - 已初始化数据库、公钥TTL和各节点一致的正安全整数maxClients,默认10000。\n * @returns registry;非法配置同步TypeError,操作故障拒绝Promise;不关闭借用数据库。\n *\n * @example\n * ```ts\n * import { createReldbTransportKeyStore } from '@h-ai/crypto'\n * import { reldb } from '@h-ai/reldb'\n * const connected = await reldb.init({ type: 'postgresql', host: 'db', port: 5432, database: 'hai', user: 'postgres', password: process.env.HAI_DB_PASSWORD })\n * if (!connected.success) throw new Error(connected.error.message)\n * try {\n * const registry = createReldbTransportKeyStore({ reldb, ttlSeconds: 3600, maxClients: 10000 })\n * const removed = await registry.pruneExpired()\n * }\n * finally { await reldb.close() }\n * ```\n */\nexport function createReldbTransportKeyStore(options: CreateReldbTransportKeyStoreOptions): ReldbTransportKeyStore {\n const { ttlSeconds } = options\n if (ttlSeconds !== undefined && (!Number.isSafeInteger(ttlSeconds) || ttlSeconds <= 0 || ttlSeconds > 2_147_483_647))\n throw new TypeError(cryptoM('crypto_transportKeyStoreTtlInvalid'))\n const maxClients = options.maxClients ?? 10000\n if (!Number.isSafeInteger(maxClients) || maxClients <= 0)\n throw new TypeError(cryptoM('crypto_transportKeyStoreCapacityInvalid'))\n let ensureTablePromise: Promise<void> | null = null\n\n /**\n * 选择当前数据库原生Unix毫秒表达式;仅来自Provider白名单,不拼接外部输入。\n * @returns 用于公钥TTL与过期维护的数据库时钟SQL;传输认证窗口仍要求节点时钟同步。\n *\n * @example 模块内部上下文\n * ```ts\n * const databaseEpochMilliseconds = nowSql()\n * ```\n */\n function nowSql(): string {\n switch (options.reldb.config?.type) {\n case 'postgresql': return 'CAST(FLOOR(EXTRACT(EPOCH FROM clock_timestamp()) * 1000) AS BIGINT)'\n case 'mysql': return 'CAST(FLOOR(UNIX_TIMESTAMP(CURRENT_TIMESTAMP(3)) * 1000) AS SIGNED)'\n default: return '(CAST(strftime(\\'%s\\', \\'now\\') AS INTEGER) * 1000 + CAST(substr(strftime(\\'%f\\', \\'now\\'), 4, 3) AS INTEGER))'\n }\n }\n\n function insertIfAbsent(table: string, columns: string, placeholders: string, key: string): string {\n return options.reldb.config?.type === 'mysql'\n ? `INSERT IGNORE INTO ${table} (${columns}) VALUES (${placeholders})`\n : `INSERT INTO ${table} (${columns}) VALUES (${placeholders}) ON CONFLICT (${key}) DO NOTHING`\n }\n\n /**\n * 首次真实操作共享惰性建表Promise,验证持久容量配置;失败仅重置自身Promise供后续重试。\n * @returns 表及共享容量行就绪;存储故障拒绝,不降级为空registry。\n *\n * @example 模块内部上下文\n * ```ts\n * await ensureTable()\n * // 模块内部上下文:options.reldb必须已经初始化。\n * ```\n */\n async function ensureTable(): Promise<void> {\n if (!ensureTablePromise) {\n const initialization = (async () => {\n unwrapResult(\n 'reldb.ddl.createTable',\n await options.reldb.ddl.createTable(TRANSPORT_KEY_TABLE, {\n client_id: { type: 'TEXT', primaryKey: true },\n public_key: { type: 'TEXT', notNull: true },\n created_at_ms: { type: 'BIGINT', notNull: true },\n expires_at_ms: { type: 'BIGINT' },\n }, true),\n )\n unwrapResult('reldb.ddl.createTable', await options.reldb.ddl.createTable(TRANSPORT_REQUEST_TABLE, {\n request_key: { type: 'TEXT', primaryKey: true },\n expires_at: { type: 'BIGINT', notNull: true },\n }, true))\n unwrapResult('reldb.ddl.createTable', await options.reldb.ddl.createTable(TRANSPORT_CAPACITY_TABLE, {\n id: { type: 'INTEGER', primaryKey: true },\n max_clients: { type: 'BIGINT', notNull: true },\n revision: { type: 'BIGINT', notNull: true },\n }, true))\n unwrapResult('reldb.sql.execute', await options.reldb.sql.execute(\n insertIfAbsent(TRANSPORT_CAPACITY_TABLE, 'id, max_clients, revision', '?, ?, ?', 'id'),\n [1, maxClients, 0],\n ))\n const capacity = unwrapResult('reldb.sql.get', await options.reldb.sql.get<{ max_clients: number | string | bigint }>(\n `SELECT max_clients FROM ${TRANSPORT_CAPACITY_TABLE} WHERE id = ?`,\n [1],\n ))\n if (!capacity || Number(capacity.max_clients) !== maxClients)\n throw new Error(cryptoM('crypto_transportKeyStoreCapacityMismatch'))\n })()\n ensureTablePromise = initialization\n try {\n await initialization\n }\n catch (error) {\n // 只复位自己持有的失败 promise;并发等待者得到同一次失败,后续调用重新初始化。\n if (ensureTablePromise === initialization)\n ensureTablePromise = null\n throw error\n }\n }\n\n return ensureTablePromise\n }\n\n async function deleteClientKey(clientId: string): Promise<void> {\n unwrapResult(\n 'reldb.sql.execute',\n await options.reldb.sql.execute(\n `DELETE FROM ${TRANSPORT_KEY_TABLE} WHERE client_id = ?`,\n [clientId],\n ),\n )\n }\n\n /**\n * 注册与维护共用数据库持久容量行锁;操作抛错使事务回滚,防跨节点超额和MySQL清理死锁。\n * @param operation - 在同一事务中执行的有界业务。\n * @returns 事务结果;失败HaiResult转换为异常再交上层HTTP边界处理。\n *\n * @example 模块内部上下文\n * ```ts\n * const removed = await withCapacityLock(async (tx) => {\n * return pruneRows(tx)\n * })\n * ```\n */\n async function withCapacityLock<T>(operation: (tx: DmlWithTxOperations) => Promise<T>): Promise<T> {\n await ensureTable()\n const result = await options.reldb.tx.wrap(async (tx) => {\n // 注册与维护使用同一持久行锁,避免 MySQL 两个清理批次互相争用行/间隙锁。\n const locked = unwrapResult('tx.execute', await tx.execute(\n `UPDATE ${TRANSPORT_CAPACITY_TABLE} SET revision = revision + 1 WHERE id = ? AND max_clients = ?`,\n [1, maxClients],\n ))\n if (locked.changes !== 1)\n throw new Error(cryptoM('crypto_transportKeyStoreCapacityMismatch'))\n return operation(tx)\n })\n return unwrapResult('reldb.tx.wrap', result)\n }\n\n /**\n * 持有容量锁时按数据库时钟有界删除过期公钥/nonce,内外两层都检查过期,不能按旧快照删有效行。\n * @param tx - 已持有容量行锁的事务操作。\n * @returns 两张表实际删除数之和,每张表最多100条。\n *\n * @example 模块内部上下文\n * ```ts\n * const removed = await withCapacityLock(pruneRows)\n * // 不直接脱离容量锁调用,避免并发维护争用。\n * ```\n */\n async function pruneRows(tx: DmlWithTxOperations): Promise<number> {\n let removed = 0\n for (const [table, id, expiry] of [[TRANSPORT_KEY_TABLE, 'client_id', 'expires_at_ms'], [TRANSPORT_REQUEST_TABLE, 'request_key', 'expires_at']]) {\n // 内外层都检查过期条件;派生表兼容 MySQL 同表删除,并发维护不按旧快照删除有效行。\n removed += unwrapResult('tx.execute', await tx.execute(\n `DELETE FROM ${table} WHERE ${expiry} <= ${nowSql()} AND ${id} IN (SELECT ${id} FROM (SELECT ${id} FROM ${table} WHERE ${expiry} <= ${nowSql()} LIMIT ${PRUNE_BATCH_SIZE}) AS expired)`,\n )).changes\n }\n return removed\n }\n\n /**\n * 显式有界维护入口,与注册持有同一容量行锁;不创建计时器,不关闭借用连接。\n * @returns 实际删除记录数;故障拒绝,可由应用调度后重试。\n *\n * @example 模块内部上下文\n * ```ts\n * const removed = await pruneExpired()\n * ```\n */\n async function pruneExpired(): Promise<number> {\n return withCapacityLock(pruneRows)\n }\n\n return {\n get stateScope() { return options.reldb.config?.type && options.reldb.config.type !== 'sqlite' ? 'shared' : 'local' },\n async register(publicKey) {\n if (!isValidSM2PublicKey(publicKey))\n throw new TypeError(cryptoM('crypto_sm2PublicKeyInvalid'))\n const clientId = `c_${globalThis.crypto.randomUUID()}`\n return withCapacityLock(async (tx) => {\n await pruneRows(tx)\n const count = unwrapResult('tx.get', await tx.get<{ total: number | string | bigint }>(\n `SELECT COUNT(*) AS total FROM ${TRANSPORT_KEY_TABLE} WHERE expires_at_ms IS NULL OR expires_at_ms > ${nowSql()}`,\n ))\n const total = Number(count?.total)\n if (!Number.isSafeInteger(total) || total < 0)\n throw new Error(cryptoM('crypto_transportKeyStoreOperationFailed'))\n if (total >= maxClients)\n throw new Error(cryptoM('crypto_transportKeyStoreCapacityReached'))\n const inserted = unwrapResult('tx.execute', await tx.execute(\n `INSERT INTO ${TRANSPORT_KEY_TABLE} (client_id, public_key, created_at_ms, expires_at_ms) VALUES (?, ?, ${nowSql()}, ${ttlSeconds === undefined ? 'NULL' : `${nowSql()} + ?`})`,\n ttlSeconds === undefined ? [clientId, publicKey] : [clientId, publicKey, ttlSeconds * 1000],\n ))\n if (inserted.changes !== 1)\n throw new Error(cryptoM('crypto_transportClientNotRegistered'))\n return clientId\n })\n },\n\n async get(clientId) {\n await ensureTable()\n\n const row = unwrapResult(\n 'reldb.sql.get',\n await options.reldb.sql.get<{ public_key: string }>(\n `SELECT public_key FROM ${TRANSPORT_KEY_TABLE} WHERE client_id = ? AND (expires_at_ms IS NULL OR expires_at_ms > ${nowSql()})`,\n [clientId],\n ),\n )\n\n return row?.public_key\n },\n\n async claimRequest(clientId, requestId, expiresAt) {\n await ensureTable()\n if (!Number.isSafeInteger(expiresAt) || expiresAt <= Date.now())\n return false\n const insertSql = options.reldb.config?.type === 'mysql'\n ? `INSERT IGNORE INTO ${TRANSPORT_REQUEST_TABLE} (request_key, expires_at) VALUES (?, ?)`\n : `INSERT INTO ${TRANSPORT_REQUEST_TABLE} (request_key, expires_at) VALUES (?, ?) ON CONFLICT (request_key) DO NOTHING`\n const inserted = unwrapResult('reldb.sql.execute', await options.reldb.sql.execute(\n insertSql,\n [JSON.stringify([clientId, requestId]), expiresAt],\n ))\n // 唯一主键约束决定胜者;连接、权限和其它 SQL 故障必须 fail-closed。\n return inserted.changes === 1\n },\n\n async delete(clientId) {\n await ensureTable()\n await deleteClientKey(clientId)\n },\n pruneExpired,\n }\n}\n"]}