secure-crypto-top-sdk 0.1.0
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/LICENSE +21 -0
- package/README.md +238 -0
- package/dist/base-v1-7dHNy.d.mts +183 -0
- package/dist/base-v1-7dHNy.d.ts +183 -0
- package/dist/client.d.mts +72 -0
- package/dist/client.d.ts +72 -0
- package/dist/client.js +1436 -0
- package/dist/client.js.map +1 -0
- package/dist/client.mjs +1406 -0
- package/dist/client.mjs.map +1 -0
- package/dist/index.d.mts +162 -0
- package/dist/index.d.ts +162 -0
- package/dist/index.js +1393 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1335 -0
- package/dist/index.mjs.map +1 -0
- package/dist/key-store-BCmOK04m.d.ts +49 -0
- package/dist/key-store-BF0_3do0.d.mts +49 -0
- package/dist/server.d.mts +60 -0
- package/dist/server.d.ts +60 -0
- package/dist/server.js +1369 -0
- package/dist/server.js.map +1 -0
- package/dist/server.mjs +1338 -0
- package/dist/server.mjs.map +1 -0
- package/package.json +70 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server/fastify-plugin.ts","../src/errors/index.ts","../src/config/app-registry.ts","../src/config/key-store.ts","../src/algorithms/cipher/aes-gcm.ts","../src/algorithms/cipher/aes-cbc.ts","../src/algorithms/cipher/sm4-cbc.ts","../src/algorithms/cipher/rsa-oaep-aes-gcm.ts","../src/algorithms/digest/hmac.ts","../src/algorithms/digest/hash.ts","../src/algorithms/digest/sm3.ts","../src/algorithms/registry.ts","../src/protocol/custom/strategy.ts","../src/protocol/top/signer.ts","../src/protocol/top/strategy.ts","../src/protocol/registry.ts"],"sourcesContent":["/**\r\n * Fastify 插件入口\r\n *\r\n * 用法:\r\n * import secureCryptoPlugin from 'secure-crypto-top-sdk/server';\r\n * await app.register(secureCryptoPlugin, {\r\n * apps: [\r\n * { appKey: 'demo', appSecret: 'xxx', allowedCiphers: ['aes-256-gcm', 'sm4-cbc'], allowedDigests: ['hmac-sha256'] }\r\n * ],\r\n * defaultProtocol: 'top',\r\n * });\r\n */\r\n\r\nimport fp from 'fastify-plugin';\r\nimport type { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';\r\nimport { AppRegistry } from '../config/app-registry';\r\nimport { KeyStore } from '../config/key-store';\r\nimport { pickProtocol, getProtocol } from '../protocol/registry';\r\nimport type { ProtocolKind } from '../protocol/base';\r\nimport { SecureError, ErrorCode } from '../errors';\r\nimport type { AppConfig, NonceStore, ServerContext } from '../types';\r\n\r\nexport interface SecureCryptoOptions {\r\n /** 应用配置列表 */\r\n apps: AppConfig[];\r\n /** 默认协议(custom | top),默认 top */\r\n defaultProtocol?: ProtocolKind;\r\n /** 跳过加解密的路径前缀 */\r\n bypassPaths?: string[];\r\n /** 跳过加解密的 HTTP 方法 */\r\n bypassMethods?: string[];\r\n /** 请求时间戳有效窗口(毫秒) */\r\n requestWindowMs?: number;\r\n /** Redis / 自实现 - nonce 防重放 */\r\n redis?: NonceStore;\r\n /** RSA 私钥 PEM(混合加密场景:服务端持有) */\r\n rsaPrivateKeyPem?: string;\r\n}\r\n\r\ndeclare module 'fastify' {\r\n interface FastifyRequest {\r\n /** 解密后的业务数据 */\r\n secureRequest?: {\r\n appKey: string;\r\n method: string;\r\n path: string;\r\n body?: unknown;\r\n query?: Record<string, string>;\r\n session?: string;\r\n /** 原始业务参数(TOP 协议下 = biz_content 解密结果) */\r\n biz: unknown;\r\n protocol: ProtocolKind;\r\n };\r\n }\r\n interface FastifyInstance {\r\n secureCrypto: {\r\n appRegistry: AppRegistry;\r\n keyStore: KeyStore;\r\n defaultProtocol: ProtocolKind;\r\n };\r\n }\r\n}\r\n\r\nconst DEFAULT_BYPASS_PATHS = ['/health', '/docs', '/docs/', '/favicon.ico', '/'];\r\nconst DEFAULT_BYPASS_METHODS = ['OPTIONS', 'HEAD'];\r\nconst DEFAULT_REQUEST_WINDOW_MS = 5 * 60 * 1000;\r\n\r\nfunction isBypass(path: string, methods: string[], m: string, bypassPaths: string[]): boolean {\r\n if (methods.includes(m.toUpperCase())) return true;\r\n if (path === '/') return true;\r\n return bypassPaths.some(p => p !== '/' && (path === p || path.startsWith(p)));\r\n}\r\n\r\nasync function secureCryptoPluginImpl(\r\n app: FastifyInstance,\r\n options: SecureCryptoOptions\r\n): Promise<void> {\r\n if (!options.apps || options.apps.length === 0) {\r\n throw new Error('[secure-crypto-top-sdk] apps 不能为空');\r\n }\r\n\r\n const registry = new AppRegistry(options.apps);\r\n const keyStore = new KeyStore();\r\n const defaultProtocol: ProtocolKind = options.defaultProtocol ?? 'top';\r\n\r\n // 暴露到 app 装饰\r\n app.decorate('secureCrypto', { appRegistry: registry, keyStore, defaultProtocol });\r\n\r\n const bypassPaths = options.bypassPaths ?? DEFAULT_BYPASS_PATHS;\r\n const bypassMethods = options.bypassMethods ?? DEFAULT_BYPASS_METHODS;\r\n const requestWindowMs = options.requestWindowMs ?? DEFAULT_REQUEST_WINDOW_MS;\r\n\r\n // ==================== 解密 / 验签 ====================\r\n app.addHook('preValidation', async (request: FastifyRequest, reply: FastifyReply) => {\r\n const path = request.url.split('?')[0];\r\n if (isBypass(path, bypassMethods, request.method, bypassPaths)) return;\r\n\r\n const body = (request.body ?? {}) as Record<string, unknown>;\r\n if (!body || typeof body !== 'object') return; // 非加密请求放过\r\n\r\n try {\r\n const protocol = pickProtocol(body, defaultProtocol);\r\n const appKey = (body.app_key as string) || (body.appKey as string);\r\n if (!appKey) {\r\n // custom 协议可能不携带 app_key,从 header 推断\r\n // 这里简单放过,交给业务层处理\r\n return;\r\n }\r\n const appConfig = registry.get(appKey);\r\n if (appConfig.allowedProtocols?.length && !appConfig.allowedProtocols.includes(protocol.kind)) {\r\n throw new SecureError(ErrorCode.PROTOCOL_NOT_FOUND, `app ${appKey} 不允许 protocol: ${protocol.kind}`);\r\n }\r\n\r\n const key = keyStore.get(appConfig);\r\n const ctx = {\r\n app: appConfig,\r\n encryptionKey: key.encryptionKey,\r\n hmacSecret: appConfig.appSecret, // 签名密钥用 appSecret\r\n rsaPrivateKeyPem: options.rsaPrivateKeyPem,\r\n nonceStore: options.redis,\r\n requestWindowMs,\r\n };\r\n\r\n const parsed = await protocol.parseAndVerify(body, ctx);\r\n\r\n request.secureRequest = {\r\n appKey: parsed.appKey,\r\n method: parsed.method,\r\n path: parsed.path,\r\n body: parsed.body,\r\n query: parsed.query,\r\n session: parsed.session,\r\n biz: parsed.biz,\r\n protocol: protocol.kind,\r\n };\r\n\r\n // 业务 body:TOP 协议下是 biz;custom 协议下是 body 字段\r\n if (protocol.kind === 'top') {\r\n request.body = parsed.biz;\r\n } else {\r\n request.body = parsed.body ?? parsed.biz;\r\n }\r\n if (parsed.query) {\r\n (request as any).query = { ...(request as any).query, ...parsed.query };\r\n }\r\n } catch (err) {\r\n if (err instanceof SecureError) {\r\n app.log.warn({ code: err.code, message: err.message }, '⚠️ 加密验证失败');\r\n return reply.status(err.statusCode).send({ success: false, code: err.code, message: err.message });\r\n }\r\n app.log.error({ err }, '❌ 解密过程异常');\r\n return reply.status(400).send({ success: false, code: ErrorCode.DECRYPTION_FAILED, message: '请求解密失败' });\r\n }\r\n });\r\n\r\n // ==================== 加密响应 ====================\r\n app.addHook('onSend', async (request: FastifyRequest, reply, payload) => {\r\n const path = request.url.split('?')[0];\r\n if (isBypass(path, bypassMethods, request.method, bypassPaths)) return payload;\r\n if (!request.secureRequest) return payload; // 非加密请求\r\n if (typeof payload === 'string' && payload.startsWith('<?xml')) return payload; // 不处理 XML\r\n\r\n try {\r\n const protocol = getProtocol(request.secureRequest.protocol);\r\n const appConfig = registry.get(request.secureRequest.appKey);\r\n const key = keyStore.get(appConfig);\r\n const env = await protocol.buildResponse(safeJsonParse(payload), {\r\n app: appConfig,\r\n encryptionKey: key.encryptionKey,\r\n hmacSecret: appConfig.appSecret,\r\n rsaPrivateKeyPem: options.rsaPrivateKeyPem,\r\n nonceStore: options.redis,\r\n requestWindowMs,\r\n });\r\n reply.header('Content-Type', 'application/json; charset=utf-8');\r\n return JSON.stringify(env);\r\n } catch (err) {\r\n app.log.error({ err }, '❌ 响应加密失败');\r\n return payload;\r\n }\r\n });\r\n\r\n app.log.info(`🔐 secure-crypto-top-sdk 插件已注册 (default protocol: ${defaultProtocol}, ${options.apps.length} apps)`);\r\n}\r\n\r\nfunction safeJsonParse(payload: unknown): unknown {\r\n if (typeof payload === 'string') {\r\n try { return JSON.parse(payload); } catch { return payload; }\r\n }\r\n return payload;\r\n}\r\n\r\nexport default fp(secureCryptoPluginImpl, {\r\n name: 'secure-crypto-top-sdk',\r\n fastify: '4.x',\r\n});\r\n","/**\r\n * 统一错误体系\r\n */\r\n\r\nexport enum ErrorCode {\r\n // 算法层 (1000-1099)\r\n ENCRYPTION_FAILED = 1000,\r\n DECRYPTION_FAILED = 1001,\r\n INVALID_AUTH_TAG = 1002,\r\n UNSUPPORTED_CIPHER = 1003,\r\n UNSUPPORTED_DIGEST = 1004,\r\n INVALID_KEY_LENGTH = 1005,\r\n INVALID_IV_LENGTH = 1006,\r\n\r\n // 签名/校验 (1100-1199)\r\n HMAC_MISMATCH = 1100,\r\n SIGNATURE_MISMATCH = 1101,\r\n TIMESTAMP_EXPIRED = 1102,\r\n NONCE_REUSED = 1103,\r\n INVALID_TIMESTAMP = 1104,\r\n SIGN_METHOD_NOT_ALLOWED = 1105,\r\n\r\n // 应用/协议 (1200-1299)\r\n APP_NOT_FOUND = 1200,\r\n APP_DISABLED = 1201,\r\n PROTOCOL_NOT_FOUND = 1202,\r\n MISSING_APP_KEY = 1203,\r\n MISSING_METHOD = 1204,\r\n\r\n // 请求格式 (1300-1399)\r\n VALIDATION_ERROR = 1300,\r\n INVALID_REQUEST = 1301,\r\n INVALID_PAYLOAD = 1302,\r\n}\r\n\r\nconst ErrorMessages: Record<ErrorCode, string> = {\r\n [ErrorCode.ENCRYPTION_FAILED]: '加密失败',\r\n [ErrorCode.DECRYPTION_FAILED]: '解密失败',\r\n [ErrorCode.INVALID_AUTH_TAG]: '认证标签无效',\r\n [ErrorCode.UNSUPPORTED_CIPHER]: '不支持的加密算法',\r\n [ErrorCode.UNSUPPORTED_DIGEST]: '不支持的摘要/签名算法',\r\n [ErrorCode.INVALID_KEY_LENGTH]: '密钥长度无效',\r\n [ErrorCode.INVALID_IV_LENGTH]: 'IV 长度无效',\r\n [ErrorCode.HMAC_MISMATCH]: 'HMAC 验证失败',\r\n [ErrorCode.SIGNATURE_MISMATCH]: '签名不匹配',\r\n [ErrorCode.TIMESTAMP_EXPIRED]: '请求已过期',\r\n [ErrorCode.NONCE_REUSED]: '请求已被处理,请勿重放',\r\n [ErrorCode.INVALID_TIMESTAMP]: '无效的时间戳',\r\n [ErrorCode.SIGN_METHOD_NOT_ALLOWED]: '该签名方法未被该 app 允许',\r\n [ErrorCode.APP_NOT_FOUND]: '未找到对应的 app 配置',\r\n [ErrorCode.APP_DISABLED]: '该 app 已被禁用',\r\n [ErrorCode.PROTOCOL_NOT_FOUND]: '未注册对应协议',\r\n [ErrorCode.MISSING_APP_KEY]: '缺少 app_key 参数',\r\n [ErrorCode.MISSING_METHOD]: '缺少 method 参数',\r\n [ErrorCode.VALIDATION_ERROR]: '数据校验失败',\r\n [ErrorCode.INVALID_REQUEST]: '请求格式错误',\r\n [ErrorCode.INVALID_PAYLOAD]: '请求载荷无效',\r\n};\r\n\r\nexport class SecureError extends Error {\r\n public readonly code: ErrorCode;\r\n public readonly statusCode: number;\r\n public readonly details?: unknown;\r\n\r\n constructor(code: ErrorCode, details?: unknown, statusCode?: number) {\r\n super(typeof details === 'string' ? details : ErrorMessages[code]);\r\n this.name = 'SecureError';\r\n this.code = code;\r\n this.statusCode = statusCode || this.getDefaultStatusCode(code);\r\n this.details = details;\r\n Error.captureStackTrace(this, this.constructor);\r\n }\r\n\r\n private getDefaultStatusCode(code: ErrorCode): number {\r\n if (code >= 1000 && code < 1100) return 400;\r\n if (code >= 1100 && code < 1200) return 401;\r\n if (code >= 1200 && code < 1300) return 403;\r\n if (code >= 1300 && code < 1400) return 400;\r\n return 500;\r\n }\r\n\r\n toJSON() {\r\n return { success: false, code: this.code, message: this.message, details: this.details };\r\n }\r\n}\r\n\r\nexport function getHttpStatus(code: ErrorCode): number {\r\n return new SecureError(code).statusCode;\r\n}\r\n","/**\r\n * App 注册表 - 集中管理 appKey -> AppConfig 的映射\r\n */\r\n\r\nimport type { AppConfig } from '../types';\r\nimport { SecureError, ErrorCode } from '../errors';\r\n\r\nexport class AppRegistry {\r\n private readonly map = new Map<string, AppConfig>();\r\n\r\n constructor(apps: AppConfig[] = []) {\r\n for (const a of apps) this.register(a);\r\n }\r\n\r\n register(app: AppConfig): this {\r\n if (!app.appKey) throw new SecureError(ErrorCode.APP_NOT_FOUND, 'appKey 不能为空');\r\n if (!app.appSecret) throw new SecureError(ErrorCode.APP_NOT_FOUND, `app ${app.appKey} 缺少 appSecret`);\r\n this.map.set(app.appKey, app);\r\n return this;\r\n }\r\n\r\n get(appKey: string): AppConfig {\r\n const app = this.map.get(appKey);\r\n if (!app) throw new SecureError(ErrorCode.APP_NOT_FOUND, `Unknown app: ${appKey}`);\r\n if (app.enabled === false) throw new SecureError(ErrorCode.APP_DISABLED, `App disabled: ${appKey}`);\r\n return app;\r\n }\r\n\r\n has(appKey: string): boolean {\r\n return this.map.has(appKey);\r\n }\r\n\r\n list(): AppConfig[] {\r\n return Array.from(this.map.values());\r\n }\r\n}\r\n","/**\r\n * 密钥管理:为不同 app 提供独立的加密密钥 / 签名密钥\r\n *\r\n * 设计:\r\n * - 默认每个 app 用自己的 appSecret 同时作为 HMAC key\r\n * - 如果需要更安全的密钥隔离,可以传入 encryptionKey(对称加密密钥 hex)\r\n * - 支持 rsaPublicKeyPem / rsaPrivateKeyPem 用于混合加密\r\n */\r\n\r\nimport * as nodeCrypto from 'crypto';\r\nimport type { AppConfig } from '../types';\r\nimport { parseKeyHex } from '../algorithms/registry';\r\n\r\nexport interface AppKeyMaterial {\r\n /** 对称加密密钥 Buffer */\r\n encryptionKey: Buffer;\r\n /** 签名密钥字符串 */\r\n hmacSecret: string;\r\n /** RSA 公钥(混合加密 - 客户端持有) */\r\n rsaPublicKeyPem?: string;\r\n /** RSA 私钥(混合加密 - 服务端持有) */\r\n rsaPrivateKeyPem?: string;\r\n}\r\n\r\nexport class KeyStore {\r\n private readonly keys = new Map<string, AppKeyMaterial>();\r\n\r\n /** 从 apps 推导默认密钥材料:对称密钥 = SHA-256(appSecret),签名密钥 = appSecret */\r\n static deriveFromApp(app: AppConfig): AppKeyMaterial {\r\n const hmacSecret = app.appSecret;\r\n const encryptionKey = nodeCrypto.createHash('sha256').update(app.appSecret).digest();\r\n return { encryptionKey, hmacSecret };\r\n }\r\n\r\n set(appKey: string, key: AppKeyMaterial): void {\r\n this.keys.set(appKey, key);\r\n }\r\n\r\n /** 懒加载:未显式 set 时,自动 derive */\r\n get(app: AppConfig): AppKeyMaterial {\r\n let k = this.keys.get(app.appKey);\r\n if (!k) {\r\n k = KeyStore.deriveFromApp(app);\r\n this.keys.set(app.appKey, k);\r\n }\r\n return k;\r\n }\r\n\r\n /** 用 hex 显式注入对称密钥(给\"对称密钥\"和\"签名密钥\"分离的场景) */\r\n setHex(appKey: string, encryptionKeyHex: string, hmacSecret: string, rsa?: { publicKey?: string; privateKey?: string }): void {\r\n const k: AppKeyMaterial = {\r\n encryptionKey: parseKeyHex(encryptionKeyHex),\r\n hmacSecret,\r\n rsaPublicKeyPem: rsa?.publicKey,\r\n rsaPrivateKeyPem: rsa?.privateKey,\r\n };\r\n this.keys.set(appKey, k);\r\n }\r\n}\r\n","/**\r\n * AES-256-GCM(Node.js / Web Crypto 通用)\r\n */\r\n\r\nimport * as nodeCrypto from 'crypto';\r\nimport { SecureError, ErrorCode } from '../../errors';\r\nimport type { Cipher, CipherMeta, EncryptParams, EncryptResult, DecryptParams } from '../types';\r\n\r\nconst META: CipherMeta = {\r\n name: 'aes-256-gcm',\r\n keyLength: 32,\r\n ivLength: 12,\r\n hasAuthTag: true,\r\n blockSize: 16,\r\n};\r\n\r\nexport const aesGcm: Cipher = {\r\n name: 'aes-256-gcm',\r\n meta: META,\r\n\r\n generateKey() {\r\n return nodeCrypto.randomBytes(META.keyLength);\r\n },\r\n\r\n generateIv() {\r\n return nodeCrypto.randomBytes(META.ivLength);\r\n },\r\n\r\n encrypt(plain: Buffer, params: EncryptParams = {}): EncryptResult {\r\n if (!params.key) {\r\n throw new SecureError(ErrorCode.INVALID_KEY_LENGTH, 'AES-256-GCM 需要传入 32 字节对称密钥');\r\n }\r\n const key = params.key;\r\n if (key.length !== META.keyLength) {\r\n throw new SecureError(ErrorCode.INVALID_KEY_LENGTH, `AES-256 密钥需 ${META.keyLength} 字节`);\r\n }\r\n const iv = params.rsaPublicKeyPem ? nodeCrypto.randomBytes(META.ivLength) : (params.iv ?? this.generateIv());\r\n const cipher = nodeCrypto.createCipheriv('aes-256-gcm', key, iv, { authTagLength: 16 });\r\n const enc = Buffer.concat([cipher.update(plain), cipher.final()]);\r\n return { data: enc, iv, tag: cipher.getAuthTag() };\r\n },\r\n\r\n decrypt(cipherBuf: Buffer, params: DecryptParams & { iv: Buffer; tag?: Buffer }): Buffer {\r\n if (!params.key) throw new SecureError(ErrorCode.INVALID_KEY_LENGTH, 'AES-256-GCM 需要密钥');\r\n if (!params.tag) throw new SecureError(ErrorCode.INVALID_AUTH_TAG, 'AES-256-GCM 需要 authTag');\r\n const decipher = nodeCrypto.createDecipheriv('aes-256-gcm', params.key, params.iv, { authTagLength: 16 });\r\n decipher.setAuthTag(params.tag);\r\n try {\r\n return Buffer.concat([decipher.update(cipherBuf), decipher.final()]);\r\n } catch {\r\n throw new SecureError(ErrorCode.INVALID_AUTH_TAG, 'AES-GCM authTag 校验失败,数据可能已被篡改');\r\n }\r\n },\r\n};\r\n","/**\r\n * AES-CBC 模式(256 / 128)\r\n * - 需要 PKCS#7 padding\r\n * - 注意:每次加密必须用新随机 IV(16 字节)\r\n */\r\n\r\nimport * as nodeCrypto from 'crypto';\r\nimport { SecureError, ErrorCode } from '../../errors';\r\nimport type { Cipher, CipherMeta, EncryptParams, EncryptResult, DecryptParams } from '../types';\r\n\r\nconst META_256: CipherMeta = {\r\n name: 'aes-256-cbc',\r\n keyLength: 32,\r\n ivLength: 16,\r\n hasAuthTag: false,\r\n blockSize: 16,\r\n};\r\n\r\nconst META_128: CipherMeta = {\r\n name: 'aes-128-cbc',\r\n keyLength: 16,\r\n ivLength: 16,\r\n hasAuthTag: false,\r\n blockSize: 16,\r\n};\r\n\r\nfunction pkcs7Pad(data: Buffer, blockSize: number): Buffer {\r\n const pad = blockSize - (data.length % blockSize);\r\n return Buffer.concat([data, Buffer.alloc(pad, pad)]);\r\n}\r\n\r\nfunction pkcs7Unpad(data: Buffer): Buffer {\r\n if (data.length === 0) return data;\r\n const pad = data[data.length - 1];\r\n if (pad < 1 || pad > data.length) {\r\n throw new SecureError(ErrorCode.DECRYPTION_FAILED, 'PKCS#7 padding 无效');\r\n }\r\n return data.subarray(0, data.length - pad);\r\n}\r\n\r\nfunction makeAesCbc(meta: CipherMeta, openSslName: string): Cipher {\r\n return {\r\n name: meta.name,\r\n meta,\r\n generateKey() { return nodeCrypto.randomBytes(meta.keyLength); },\r\n generateIv() { return nodeCrypto.randomBytes(meta.ivLength); },\r\n\r\n encrypt(plain: Buffer, params: EncryptParams = {}): EncryptResult {\r\n if (!params.key || params.key.length !== meta.keyLength) {\r\n throw new SecureError(ErrorCode.INVALID_KEY_LENGTH, `${meta.name} 密钥需 ${meta.keyLength} 字节`);\r\n }\r\n const iv = nodeCrypto.randomBytes(meta.ivLength);\r\n // 关掉 autoPadding,我们自己处理 PKCS#7\r\n const cipher = nodeCrypto.createCipheriv(openSslName, params.key, iv);\r\n cipher.setAutoPadding(false);\r\n const padded = pkcs7Pad(plain, meta.blockSize);\r\n const enc = Buffer.concat([cipher.update(padded), cipher.final()]);\r\n return { data: enc, iv };\r\n },\r\n\r\n decrypt(cipherBuf: Buffer, params: DecryptParams): Buffer {\r\n if (!params.key || params.key.length !== meta.keyLength) {\r\n throw new SecureError(ErrorCode.INVALID_KEY_LENGTH, `${meta.name} 密钥需 ${meta.keyLength} 字节`);\r\n }\r\n const decipher = nodeCrypto.createDecipheriv(openSslName, params.key, params.iv);\r\n decipher.setAutoPadding(false);\r\n const dec = Buffer.concat([decipher.update(cipherBuf), decipher.final()]);\r\n return pkcs7Unpad(dec);\r\n },\r\n };\r\n}\r\n\r\nexport const aesCbc256: Cipher = makeAesCbc(META_256, 'aes-256-cbc');\r\nexport const aesCbc128: Cipher = makeAesCbc(META_128, 'aes-128-cbc');\r\n","/**\r\n * SM4-CBC(国密对称分组算法)\r\n *\r\n * 注意:Node.js 的 crypto 模块**不直接支持 SM4**,这里做两件事:\r\n * 1) 优先用 Node.js 原生 SM4(>= 19.x 部分构建支持),失败则降级到纯 JS 实现\r\n * 2) 纯 JS 实现采用 S-box 规范(GB/T 32907-2016),效率较低但可移植\r\n *\r\n * 如果你的运行环境不支持 SM4,推荐引入 `gm-crypt`:\r\n * import { SM4 } from 'gm-crypt';\r\n * // 自行替换 encrypt/decrypt 内部实现\r\n */\r\n\r\nimport * as nodeCrypto from 'crypto';\r\nimport { SecureError, ErrorCode } from '../../errors';\r\nimport type { Cipher, CipherMeta, EncryptParams, EncryptResult, DecryptParams } from '../types';\r\n\r\nconst META: CipherMeta = {\r\n name: 'sm4-cbc',\r\n keyLength: 16,\r\n ivLength: 16,\r\n hasAuthTag: false,\r\n blockSize: 16,\r\n};\r\n\r\nconst SBOX = [\r\n 0xd6,0x90,0xe9,0xfe,0xcc,0xe1,0x3d,0xb7,0x16,0xb6,0x14,0xc2,0x28,0xfb,0x2c,0x05,\r\n 0x2b,0x67,0x9a,0x76,0x2a,0xbe,0x04,0xc3,0xaa,0x44,0x13,0x26,0x49,0x86,0x06,0x99,\r\n 0x9c,0x42,0x50,0xf4,0x91,0xef,0x98,0x7a,0x33,0x54,0x0b,0x43,0xed,0xcf,0xac,0x62,\r\n 0xe4,0xb3,0x1c,0xa9,0xc9,0x08,0xe8,0x95,0x80,0xdf,0x94,0xfa,0x75,0x8f,0x3f,0xa6,\r\n 0x47,0x07,0xa7,0xfc,0xf3,0x73,0x17,0xba,0x83,0x59,0x3c,0x19,0xe6,0x85,0x4f,0xa8,\r\n 0x68,0x6b,0x81,0xb2,0x71,0x64,0xda,0x8b,0xf8,0xeb,0x0f,0x4b,0x70,0x56,0x9d,0x35,\r\n 0x1e,0x24,0x0e,0x5e,0x63,0x58,0xd1,0xa2,0x25,0x22,0x7c,0x3b,0x01,0x21,0x78,0x87,\r\n 0xd4,0x00,0x46,0x57,0x9f,0xd3,0x27,0x52,0x4c,0x36,0x02,0xe7,0xa0,0xc4,0xc8,0x9e,\r\n 0xea,0xbf,0x8a,0xd2,0x40,0xc7,0x38,0xb5,0xa3,0xf7,0xf2,0xce,0xf9,0x61,0x15,0xa1,\r\n 0xe0,0xae,0x5d,0xa4,0x9b,0x34,0x1a,0x55,0xad,0x93,0x32,0x30,0xf5,0x8c,0xb1,0xe3,\r\n 0x1d,0xf6,0xe2,0x2e,0x82,0x66,0xca,0x60,0xc0,0x29,0x23,0xab,0x0d,0x53,0x4e,0x6f,\r\n 0xd5,0xdb,0x37,0x45,0xde,0xfd,0x8e,0x2f,0x03,0xff,0x6a,0x72,0x6d,0x6c,0x5b,0x51,\r\n 0x8d,0x1b,0xaf,0x92,0xbb,0xdd,0xbc,0x7f,0x11,0xd9,0x5c,0x41,0x1f,0x10,0x5a,0xd8,\r\n 0x0a,0xc1,0x31,0x88,0xa5,0xcd,0x7b,0xbd,0x2d,0x74,0xd0,0x12,0xb8,0xe5,0xb4,0xb0,\r\n 0x89,0x69,0x97,0x4a,0x0c,0x96,0x77,0x7e,0x65,0xb9,0xf1,0x09,0xc5,0x6e,0xc6,0x84,\r\n 0x18,0xf0,0x7d,0xec,0x3a,0xdc,0x4d,0x20,0x79,0xee,0x5f,0x3e,0xd7,0xcb,0x39,0x48,\r\n];\r\n\r\nconst FK = [0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc];\r\nconst CK = [\r\n 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,\r\n 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,\r\n 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,\r\n 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,\r\n 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,\r\n 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,\r\n 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,\r\n 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279,\r\n];\r\n\r\nfunction rotl(x: number, n: number) { return ((x << n) | (x >>> (32 - n))) >>> 0; }\r\nfunction bytesToU32(b: Buffer, off: number): number {\r\n return ((b[off] << 24) | (b[off+1] << 16) | (b[off+2] << 8) | b[off+3]) >>> 0;\r\n}\r\nfunction u32ToBytes(x: number, b: Buffer, off: number) {\r\n b[off] = (x >>> 24) & 0xff;\r\n b[off+1] = (x >>> 16) & 0xff;\r\n b[off+2] = (x >>> 8) & 0xff;\r\n b[off+3] = x & 0xff;\r\n}\r\nfunction tau(a: number): number {\r\n return (SBOX[(a >>> 24) & 0xff] << 24) |\r\n (SBOX[(a >>> 16) & 0xff] << 16) |\r\n (SBOX[(a >>> 8) & 0xff] << 8) |\r\n (SBOX[ a & 0xff]);\r\n}\r\nfunction L(b: number): number {\r\n return b ^ rotl(b, 2) ^ rotl(b, 10) ^ rotl(b, 18) ^ rotl(b, 24);\r\n}\r\nfunction Lp(b: number): number {\r\n return b ^ rotl(b, 13) ^ rotl(b, 23);\r\n}\r\nfunction T(x: number) { return L(tau(x)); }\r\nfunction Tp(x: number) { return Lp(tau(x)); }\r\n\r\nfunction expandKey(key: Buffer): number[] {\r\n const MK = new Array(4);\r\n for (let i = 0; i < 4; i++) MK[i] = bytesToU32(key, i * 4);\r\n const rk: number[] = new Array(32);\r\n for (let i = 0; i < 32; i++) {\r\n const k1 = MK[i] ^ CK[i];\r\n rk[i] = k1 ^ Tp(k1 ^ MK[(i+1)%4] ^ MK[(i+2)%4] ^ MK[(i+3)%4]);\r\n }\r\n return rk;\r\n}\r\n\r\nfunction cryptBlock(input: Buffer, off: number, rk: number[]): number[] {\r\n const X = new Array(36);\r\n for (let i = 0; i < 4; i++) X[i] = bytesToU32(input, off + i * 4);\r\n for (let i = 0; i < 32; i++) {\r\n X[i+4] = X[i] ^ T(X[i+1] ^ X[i+2] ^ X[i+3] ^ rk[i]);\r\n }\r\n return [X[35], X[34], X[33], X[32]]; // 反序输出\r\n}\r\n\r\nfunction pkcs7Pad(data: Buffer, blockSize: number): Buffer {\r\n const pad = blockSize - (data.length % blockSize);\r\n return Buffer.concat([data, Buffer.alloc(pad, pad)]);\r\n}\r\nfunction pkcs7Unpad(data: Buffer): Buffer {\r\n if (data.length === 0) return data;\r\n const pad = data[data.length - 1];\r\n if (pad < 1 || pad > data.length) throw new SecureError(ErrorCode.DECRYPTION_FAILED, 'PKCS#7 padding 无效');\r\n return data.subarray(0, data.length - pad);\r\n}\r\n\r\nfunction xorBlock(a: Buffer, b: Buffer): Buffer {\r\n const out = Buffer.alloc(a.length);\r\n for (let i = 0; i < a.length; i++) out[i] = a[i] ^ b[i];\r\n return out;\r\n}\r\n\r\nexport const sm4Cbc: Cipher = {\r\n name: 'sm4-cbc',\r\n meta: META,\r\n generateKey(): Buffer {\r\n return nodeCrypto.randomBytes(META.keyLength);\r\n },\r\n generateIv(): Buffer {\r\n return nodeCrypto.randomBytes(META.ivLength);\r\n },\r\n\r\n encrypt(plain: Buffer, params: EncryptParams = {}): EncryptResult {\r\n if (!params.key || params.key.length !== 16) {\r\n throw new SecureError(ErrorCode.INVALID_KEY_LENGTH, 'SM4 密钥需 16 字节');\r\n }\r\n const rk = expandKey(params.key);\r\n const iv = nodeCrypto.randomBytes(META.ivLength);\r\n const padded = pkcs7Pad(plain, META.blockSize);\r\n const out = Buffer.alloc(padded.length);\r\n let prev = iv;\r\n for (let off = 0; off < padded.length; off += 16) {\r\n const block = xorBlock(padded.subarray(off, off + 16), prev);\r\n const r = cryptBlock(block, 0, rk);\r\n const enc = Buffer.alloc(16);\r\n for (let i = 0; i < 4; i++) u32ToBytes(r[i], enc, i * 4);\r\n out.set(enc, off);\r\n prev = enc;\r\n }\r\n return { data: out, iv };\r\n },\r\n\r\n decrypt(cipherBuf: Buffer, params: DecryptParams): Buffer {\r\n if (!params.key || params.key.length !== 16) {\r\n throw new SecureError(ErrorCode.INVALID_KEY_LENGTH, 'SM4 密钥需 16 字节');\r\n }\r\n if (params.iv.length !== 16) {\r\n throw new SecureError(ErrorCode.INVALID_IV_LENGTH, 'SM4 IV 需 16 字节');\r\n }\r\n // SM4 解密时,轮密钥要反序\r\n const rk = expandKey(params.key).slice().reverse();\r\n const out = Buffer.alloc(cipherBuf.length);\r\n let prev = params.iv;\r\n for (let off = 0; off < cipherBuf.length; off += 16) {\r\n const enc = cipherBuf.subarray(off, off + 16);\r\n const r = cryptBlock(enc, 0, rk);\r\n const dec = Buffer.alloc(16);\r\n for (let i = 0; i < 4; i++) u32ToBytes(r[i], dec, i * 4);\r\n const plain = xorBlock(dec, prev);\r\n out.set(plain, off);\r\n prev = enc;\r\n }\r\n return pkcs7Unpad(out);\r\n },\r\n};\r\n","/**\r\n * 混合加密:RSA-OAEP(SHA-256) 包装 AES-256-GCM 密钥\r\n * - 加密:随机生成 32 字节 AES key + 12 字节 IV,数据用 AES-GCM 加密,AES key 用 RSA-OAEP 加密\r\n * - 解密:用 RSA 私钥解开 AES key,再用 AES key 解密\r\n *\r\n * 这种方式可以做到:\r\n * - 客户端持有 RSA 公钥(嵌入 SDK)\r\n * - 服务端持有 RSA 私钥\r\n * - 每次请求 AES key 都是临时的 → 前向安全\r\n */\r\n\r\nimport * as nodeCrypto from 'crypto';\r\nimport { SecureError, ErrorCode } from '../../errors';\r\nimport type { Cipher, CipherMeta, EncryptParams, EncryptResult, DecryptParams } from '../types';\r\nimport { aesGcm } from './aes-gcm';\r\n\r\nconst META: CipherMeta = {\r\n name: 'rsa-oaep-aes-256-gcm',\r\n keyLength: 32, // 对称密钥长度\r\n ivLength: 12, // GCM IV 长度\r\n hasAuthTag: true,\r\n blockSize: 16,\r\n};\r\n\r\nexport const rsaOaepAesGcm: Cipher = {\r\n name: 'rsa-oaep-aes-256-gcm',\r\n meta: META,\r\n\r\n generateKey() {\r\n return nodeCrypto.randomBytes(META.keyLength);\r\n },\r\n\r\n generateIv() {\r\n return nodeCrypto.randomBytes(META.ivLength);\r\n },\r\n\r\n encrypt(plain: Buffer, params: EncryptParams = {}): EncryptResult {\r\n if (!params.rsaPublicKeyPem) {\r\n throw new SecureError(ErrorCode.ENCRYPTION_FAILED, 'rsa-oaep-aes-256-gcm 需要 rsaPublicKeyPem');\r\n }\r\n // 1. 临时 AES key + IV\r\n const aesKey = nodeCrypto.randomBytes(32);\r\n const iv = nodeCrypto.randomBytes(12);\r\n // 2. AES-GCM 加密数据\r\n const r = aesGcm.encrypt(plain, { key: aesKey, iv });\r\n // 3. RSA-OAEP 加密 AES key\r\n const encryptedKey = nodeCrypto.publicEncrypt(\r\n { key: params.rsaPublicKeyPem, padding: nodeCrypto.constants.RSA_PKCS1_OAEP_PADDING, oaepHash: 'sha256' },\r\n aesKey\r\n );\r\n return { data: r.data, iv: r.iv, tag: r.tag, encryptedKey };\r\n },\r\n\r\n decrypt(cipherBuf: Buffer, params: DecryptParams & { iv: Buffer; tag?: Buffer; encryptedKey?: Buffer }): Buffer {\r\n if (!params.rsaPrivateKeyPem) {\r\n throw new SecureError(ErrorCode.DECRYPTION_FAILED, 'rsa-oaep-aes-256-gcm 需要 rsaPrivateKeyPem');\r\n }\r\n if (!params.encryptedKey) {\r\n throw new SecureError(ErrorCode.DECRYPTION_FAILED, '缺少 encryptedKey');\r\n }\r\n // 1. 用 RSA 私钥解出 AES key\r\n const aesKey = nodeCrypto.privateDecrypt(\r\n { key: params.rsaPrivateKeyPem, padding: nodeCrypto.constants.RSA_PKCS1_OAEP_PADDING, oaepHash: 'sha256' },\r\n params.encryptedKey\r\n );\r\n // 2. AES-GCM 解密\r\n return aesGcm.decrypt(cipherBuf, { key: aesKey, iv: params.iv, tag: params.tag! });\r\n },\r\n};\r\n","/**\r\n * HMAC-SHA256 / HMAC-SHA512\r\n */\r\n\r\nimport * as nodeCrypto from 'crypto';\r\nimport type { Digest, DigestMeta } from '../types';\r\nimport { SecureError, ErrorCode } from '../../errors';\r\n\r\nconst META_256: DigestMeta = {\r\n name: 'hmac-sha256',\r\n outputLength: 32,\r\n keyed: true,\r\n minKeyLength: 16,\r\n};\r\n\r\nconst META_512: DigestMeta = {\r\n name: 'hmac-sha512',\r\n outputLength: 64,\r\n keyed: true,\r\n minKeyLength: 16,\r\n};\r\n\r\nfunction makeHmac(meta: DigestMeta, algo: string): Digest {\r\n return {\r\n name: meta.name,\r\n meta,\r\n sign(data: string | Buffer, key?: string | Buffer): string {\r\n if (!key) throw new SecureError(ErrorCode.INVALID_KEY_LENGTH, `${meta.name} 需要密钥`);\r\n const keyBuf = typeof key === 'string' ? Buffer.from(key, 'utf-8') : key;\r\n if (keyBuf.length < meta.minKeyLength) {\r\n throw new SecureError(ErrorCode.INVALID_KEY_LENGTH, `${meta.name} 密钥至少 ${meta.minKeyLength} 字节`);\r\n }\r\n const dataBuf = typeof data === 'string' ? Buffer.from(data, 'utf-8') : data;\r\n return nodeCrypto.createHmac(algo, keyBuf).update(dataBuf).digest('hex');\r\n },\r\n verify(sig: string, data: string | Buffer, key?: string | Buffer): boolean {\r\n const expected = this.sign(data, key);\r\n try {\r\n return nodeCrypto.timingSafeEqual(Buffer.from(sig, 'hex'), Buffer.from(expected, 'hex'));\r\n } catch {\r\n return false;\r\n }\r\n },\r\n };\r\n}\r\n\r\nexport const hmacSha256: Digest = makeHmac(META_256, 'sha256');\r\nexport const hmacSha512: Digest = makeHmac(META_512, 'sha512');\r\n","/**\r\n * MD5 / SHA-256 (非密钥散列)\r\n *\r\n * 注意:MD5 已被认为不安全,仅用于兼容老接口;默认应在 app.allowedDigests 中显式开启。\r\n */\r\n\r\nimport * as nodeCrypto from 'crypto';\r\nimport type { Digest, DigestMeta } from '../types';\r\n\r\nconst META_MD5: DigestMeta = {\r\n name: 'md5',\r\n outputLength: 16,\r\n keyed: false,\r\n minKeyLength: 0,\r\n};\r\n\r\nconst META_SHA256: DigestMeta = {\r\n name: 'sha256',\r\n outputLength: 32,\r\n keyed: false,\r\n minKeyLength: 0,\r\n};\r\n\r\nfunction makeHash(meta: DigestMeta, algo: string): Digest {\r\n return {\r\n name: meta.name,\r\n meta,\r\n sign(data: string | Buffer): string {\r\n const dataBuf = typeof data === 'string' ? Buffer.from(data, 'utf-8') : data;\r\n return nodeCrypto.createHash(algo).update(dataBuf).digest('hex');\r\n },\r\n // 非密钥散列的\"verify\"是直接比较\r\n verify(sig: string, data: string | Buffer): boolean {\r\n try {\r\n return this.sign(data) === sig.toLowerCase();\r\n } catch {\r\n return false;\r\n }\r\n },\r\n };\r\n}\r\n\r\nexport const md5: Digest = makeHash(META_MD5, 'md5');\r\nexport const sha256: Digest = makeHash(META_SHA256, 'sha256');\r\n","/**\r\n * SM3(国密散列) - 纯 JS 实现\r\n *\r\n * 输出 256 bit(32 字节)摘要,等同 SHA-256 强度\r\n * 参考:GB/T 32905-2016\r\n */\r\n\r\nimport type { Digest, DigestMeta } from '../types';\r\n\r\nconst META: DigestMeta = {\r\n name: 'sm3',\r\n outputLength: 32,\r\n keyed: false,\r\n minKeyLength: 0,\r\n};\r\n\r\nconst IV = new Uint32Array([\r\n 0x7380166f, 0x4914b2b9, 0x172442d7, 0xda8a0600,\r\n 0xa96f30bc, 0x163138aa, 0xe38dee4d, 0xb0fb0e4e,\r\n]);\r\n\r\nfunction rotl(x: number, n: number) { return ((x << n) | (x >>> (32 - n))) >>> 0; }\r\n\r\nfunction P0(x: number) { return x ^ rotl(x, 9) ^ rotl(x, 17); }\r\nfunction P1(x: number) { return x ^ rotl(x, 15) ^ rotl(x, 23); }\r\nfunction FF(x: number, y: number, z: number, j: number) {\r\n return j < 16 ? x ^ y ^ z : (x & y) | (x & z) | (y & z);\r\n}\r\nfunction GG(x: number, y: number, z: number, j: number) {\r\n return j < 16 ? x ^ y ^ z : (x & y) | (~x & z) >>> 0;\r\n}\r\n\r\nfunction Tj(j: number) {\r\n return j < 16 ? 0x79cc4519 : 0x7a879d8a;\r\n}\r\n\r\nfunction CF(V: Uint32Array, B: Uint32Array): Uint32Array {\r\n const W = new Uint32Array(68);\r\n const W1 = new Uint32Array(64);\r\n for (let i = 0; i < 16; i++) W[i] = B[i];\r\n for (let i = 16; i < 68; i++) {\r\n W[i] = P1(W[i-16] ^ W[i-9] ^ rotl(W[i-3], 15)) ^ rotl(W[i-13], 7) ^ W[i-6];\r\n }\r\n for (let i = 0; i < 64; i++) W1[i] = W[i] ^ W[i+4];\r\n\r\n let A = V[0], Bb = V[1], C = V[2], D = V[3];\r\n let E = V[4], F = V[5], G = V[6], H = V[7];\r\n for (let j = 0; j < 64; j++) {\r\n const SS1 = rotl(rotl(A, 12) + E + rotl(Tj(j), j), 7);\r\n const SS2 = SS1 ^ rotl(A, 12);\r\n const TT1 = (FF(A, Bb, C, j) + D + SS2 + W1[j]) >>> 0;\r\n const TT2 = (GG(E, F, G, j) + H + SS1 + W[j]) >>> 0;\r\n D = C; C = rotl(Bb, 9); Bb = A; A = TT1;\r\n H = G; G = rotl(F, 19); F = E; E = P0(TT2);\r\n }\r\n return new Uint32Array([\r\n V[0] ^ A, V[1] ^ Bb, V[2] ^ C, V[3] ^ D,\r\n V[4] ^ E, V[5] ^ F, V[6] ^ G, V[7] ^ H,\r\n ]);\r\n}\r\n\r\nfunction sm3Hash(data: Buffer): Buffer {\r\n // padding\r\n const bitLen = BigInt(data.length) * 8n;\r\n const padLen = (56 - (data.length + 1) % 64 + 64) % 64;\r\n const padded = Buffer.alloc(data.length + 1 + padLen + 8);\r\n data.copy(padded, 0);\r\n padded[data.length] = 0x80;\r\n // 写入 64-bit 大端长度\r\n for (let i = 0; i < 8; i++) {\r\n padded[padded.length - 1 - i] = Number((bitLen >> BigInt(i * 8)) & 0xffn);\r\n }\r\n\r\n const V = new Uint32Array(IV);\r\n for (let off = 0; off < padded.length; off += 64) {\r\n const B = new Uint32Array(16);\r\n for (let i = 0; i < 16; i++) {\r\n B[i] = padded.readUInt32BE(off + i * 4);\r\n }\r\n const Vn = CF(V, B);\r\n for (let i = 0; i < 8; i++) V[i] = Vn[i];\r\n }\r\n const out = Buffer.alloc(32);\r\n for (let i = 0; i < 8; i++) V[i] = V[i] >>> 0, out.writeUInt32BE(V[i], i * 4);\r\n return out;\r\n}\r\n\r\nexport const sm3: Digest = {\r\n name: 'sm3',\r\n meta: META,\r\n sign(data: string | Buffer): string {\r\n const buf = typeof data === 'string' ? Buffer.from(data, 'utf-8') : data;\r\n return sm3Hash(buf).toString('hex');\r\n },\r\n verify(sig: string, data: string | Buffer): boolean {\r\n try {\r\n return this.sign(data) === sig.toLowerCase();\r\n } catch {\r\n return false;\r\n }\r\n },\r\n};\r\n","/**\r\n * 算法注册表:集中管理所有可用的 cipher / digest 实现\r\n * 新增算法只需:实现接口 -> 在这里注册\r\n */\r\n\r\nimport type { Cipher, CipherAlgorithm, Digest, DigestAlgorithm } from './types';\r\nimport { SecureError, ErrorCode } from '../errors';\r\nimport { aesGcm, aesCbc256, aesCbc128, sm4Cbc, rsaOaepAesGcm } from './cipher';\r\nimport { hmacSha256, hmacSha512, md5, sha256, sm3 } from './digest';\r\n\r\n// ============================================\r\n// Cipher Registry\r\n// ============================================\r\nexport const cipherRegistry = new Map<CipherAlgorithm, Cipher>([\r\n ['aes-256-gcm', aesGcm],\r\n ['aes-256-cbc', aesCbc256],\r\n ['aes-128-cbc', aesCbc128],\r\n ['sm4-cbc', sm4Cbc],\r\n ['rsa-oaep-aes-256-gcm', rsaOaepAesGcm],\r\n]);\r\n\r\n/** 获取 cipher 实现;未注册时抛错 */\r\nexport function getCipher(name: CipherAlgorithm): Cipher {\r\n const c = cipherRegistry.get(name);\r\n if (!c) {\r\n throw new SecureError(ErrorCode.UNSUPPORTED_CIPHER, `Unsupported cipher: ${name}`);\r\n }\r\n return c;\r\n}\r\n\r\n// ============================================\r\n// Digest Registry\r\n// ============================================\r\nexport const digestRegistry = new Map<DigestAlgorithm, Digest>([\r\n ['hmac-sha256', hmacSha256],\r\n ['hmac-sha512', hmacSha512],\r\n ['md5', md5],\r\n ['sha256', sha256],\r\n ['sm3', sm3],\r\n]);\r\n\r\nexport function getDigest(name: DigestAlgorithm): Digest {\r\n const d = digestRegistry.get(name);\r\n if (!d) {\r\n throw new SecureError(ErrorCode.UNSUPPORTED_DIGEST, `Unsupported digest: ${name}`);\r\n }\r\n return d;\r\n}\r\n\r\n// ============================================\r\n// 工具:从 hex / utf8 获取 Buffer\r\n// ============================================\r\n\r\n/** 解析 64 字符 hex 为 32 字节 Buffer(AES-256 密钥) */\r\nexport function parseKeyHex(hex: string, expectedLength: number = 32): Buffer {\r\n if (!hex || hex.length !== expectedLength * 2) {\r\n throw new SecureError(\r\n ErrorCode.INVALID_KEY_LENGTH,\r\n `Key hex 长度需为 ${expectedLength * 2} 字符(对应 ${expectedLength} 字节)`\r\n );\r\n }\r\n return Buffer.from(hex, 'hex');\r\n}\r\n\r\n/** 解析 utf8 secret 为 Buffer(用于 HMAC,要求长度>= minKey) */\r\nexport function parseSecret(secret: string, minLength: number = 32): Buffer {\r\n if (!secret || secret.length < minLength) {\r\n throw new SecureError(\r\n ErrorCode.INVALID_KEY_LENGTH,\r\n `Secret 长度需至少 ${minLength} 字符`\r\n );\r\n }\r\n return Buffer.from(secret, 'utf-8');\r\n}\r\n","/**\r\n * Custom 协议 - 直接对齐 secure-crypto-sdk 现有的格式\r\n *\r\n * 信封:\r\n * {\r\n * protocol: \"custom\",\r\n * encryptedPayload, iv, authTag, // 加密整个 {path, method, body, query}\r\n * signature, timestamp, nonce\r\n * }\r\n *\r\n * 签名内容: timestamp + nonce + encrypted + iv + authTag\r\n */\r\n\r\nimport * as nodeCrypto from 'crypto';\r\nimport type {\r\n ProtocolStrategy, ProtocolRequestInput, ProtocolClientContext, ProtocolServerContext, ProtocolVerifyResult,\r\n} from '../base';\r\nimport { getCipher, getDigest } from '../../algorithms/registry';\r\nimport { SecureError, ErrorCode } from '../../errors';\r\n\r\nconst PROTOCOL = 'custom';\r\n\r\nexport const customProtocol: ProtocolStrategy = {\r\n kind: PROTOCOL,\r\n\r\n async buildRequest(input, ctx) {\r\n const cipherName = input.cipher || 'aes-256-gcm';\r\n const cipher = getCipher(cipherName);\r\n const digest = getDigest(input.digest || 'hmac-sha256');\r\n\r\n const payload = JSON.stringify({\r\n path: input.path,\r\n method: input.method,\r\n body: input.body,\r\n query: input.query,\r\n });\r\n\r\n const r = cipher.encrypt(Buffer.from(payload, 'utf-8'), { key: ctx.encryptionKey });\r\n\r\n const timestamp = Date.now();\r\n const nonce = nodeCrypto.randomUUID();\r\n const signData = `${timestamp}.${nonce}.${r.data.toString('base64')}.${r.iv.toString('base64')}.${(r.tag ?? Buffer.alloc(0)).toString('base64')}`;\r\n const signature = digest.sign(signData, ctx.hmacSecret);\r\n\r\n const envelope: Record<string, unknown> = {\r\n protocol: PROTOCOL,\r\n app_key: ctx.appKey,\r\n cipher: cipherName,\r\n encryptedPayload: r.data.toString('base64'),\r\n iv: r.iv.toString('base64'),\r\n timestamp,\r\n nonce,\r\n signature,\r\n };\r\n if (r.tag) envelope.authTag = r.tag.toString('base64');\r\n if (r.encryptedKey) envelope.encryptedKey = r.encryptedKey.toString('base64');\r\n return envelope;\r\n },\r\n\r\n async parseAndVerify(raw, ctx) {\r\n // 1. 字段\r\n const encryptedPayload = raw.encryptedPayload as string;\r\n const iv = raw.iv as string;\r\n const authTag = raw.authTag as string | undefined;\r\n const signature = raw.signature as string;\r\n const timestamp = raw.timestamp as number;\r\n const nonce = raw.nonce as string;\r\n const encryptedKey = raw.encryptedKey as string | undefined;\r\n const cipherName = (raw.cipher as import('../../algorithms/types').CipherAlgorithm) || 'aes-256-gcm';\r\n\r\n if (!encryptedPayload || !iv || !signature || !timestamp || !nonce) {\r\n throw new SecureError(ErrorCode.INVALID_REQUEST, 'Custom 协议字段缺失');\r\n }\r\n\r\n // 2. 时间戳\r\n validateTimestamp(timestamp, ctx.requestWindowMs);\r\n\r\n // 3. nonce\r\n await checkNonce(ctx.nonceStore, nonce, ctx.requestWindowMs);\r\n\r\n // 4. 签名验证\r\n const digest = getDigest('hmac-sha256'); // custom 协议固定 hmac-sha256(向后兼容)\r\n const signData = `${timestamp}.${nonce}.${encryptedPayload}.${iv}.${authTag ?? ''}`;\r\n if (!digest.verify(signature, signData, ctx.app.appSecret)) {\r\n throw new SecureError(ErrorCode.SIGNATURE_MISMATCH, 'Custom 协议签名验证失败');\r\n }\r\n\r\n // 5. 解密\r\n const cipher = getCipher(cipherName);\r\n const plain = cipher.decrypt(Buffer.from(encryptedPayload, 'base64'), {\r\n key: ctx.encryptionKey,\r\n iv: Buffer.from(iv, 'base64'),\r\n tag: authTag ? Buffer.from(authTag, 'base64') : undefined,\r\n });\r\n const json = JSON.parse(plain.toString('utf-8'));\r\n return {\r\n appKey: ctx.app.appKey,\r\n method: json.method,\r\n path: json.path,\r\n body: json.body,\r\n query: json.query,\r\n biz: json,\r\n };\r\n },\r\n\r\n async buildResponse(biz, ctx) {\r\n const cipher = getCipher('aes-256-gcm');\r\n const digest = getDigest('hmac-sha256');\r\n const r = cipher.encrypt(Buffer.from(JSON.stringify(biz), 'utf-8'), { key: ctx.encryptionKey });\r\n const timestamp = Date.now();\r\n const nonce = (ctx as any).nonce || nodeCrypto.randomUUID();\r\n const signData = `${timestamp}.${nonce}.${r.data.toString('base64')}.${r.iv.toString('base64')}.${(r.tag ?? Buffer.alloc(0)).toString('base64')}`;\r\n const signature = digest.sign(signData, ctx.app.appSecret);\r\n return {\r\n protocol: PROTOCOL,\r\n encryptedPayload: r.data.toString('base64'),\r\n iv: r.iv.toString('base64'),\r\n authTag: r.tag?.toString('base64'),\r\n signature,\r\n timestamp,\r\n nonce,\r\n };\r\n },\r\n};\r\n\r\nfunction validateTimestamp(ts: number, windowMs: number) {\r\n const now = Date.now();\r\n if (ts > now + 5000) throw new SecureError(ErrorCode.INVALID_TIMESTAMP, '时间戳来自未来');\r\n if (now - ts > windowMs) throw new SecureError(ErrorCode.TIMESTAMP_EXPIRED, '请求已过期');\r\n}\r\n\r\nasync function checkNonce(store: ProtocolServerContext['nonceStore'], nonce: string, windowMs: number) {\r\n if (!store) return;\r\n const ttl = Math.ceil((windowMs * 2) / 1000);\r\n const r = await store.set(`nonce:${nonce}`, '1', 'EX', ttl, 'NX');\r\n if (r === null) throw new SecureError(ErrorCode.NONCE_REUSED, 'nonce 已被使用');\r\n}\r\n","/**\r\n * TOP 风格签名规则\r\n *\r\n * 业务参数排序拼接规则:\r\n * - 排除系统参数\r\n * - 按 key 升序排序\r\n * - 拼接格式: key1value1key2value2...keyNvalueN\r\n *\r\n * 加签内容:\r\n * signSource = (bizStr) + secret + (cipherText)\r\n * sign = digest(signSource, secret)\r\n *\r\n * 注:不同厂商的\"加 secret\"位置可能不同(头部/尾部/不参与);\r\n * 如需对接真实网关,可通过 TOP 协议配置调整\r\n */\r\n\r\nimport type { Digest } from '../../algorithms/types';\r\n\r\nconst SYSTEM_PARAMS = new Set([\r\n 'protocol',\r\n 'method', 'app_key', 'session', 'timestamp', 'v',\r\n 'sign_method', 'sign', 'format', 'simplify',\r\n 'target_app_key', 'session_auth_token',\r\n 'cipher', 'digest',\r\n 'biz_content', // TOP 把整个业务内容 base64 后放在这个字段\r\n 'encrypted_key', // 混合加密场景\r\n]);\r\n\r\nexport function buildSortedParams(input: Record<string, unknown>, includeSystem = false): string {\r\n const filtered: Record<string, unknown> = {};\r\n for (const [k, v] of Object.entries(input)) {\r\n if (v === undefined || v === null) continue;\r\n if (!includeSystem && SYSTEM_PARAMS.has(k)) continue;\r\n filtered[k] = v;\r\n }\r\n const keys = Object.keys(filtered).sort();\r\n return keys.map(k => k + stringifyVal(filtered[k])).join('');\r\n}\r\n\r\nfunction stringifyVal(v: unknown): string {\r\n if (v === null || v === undefined) return '';\r\n if (typeof v === 'object') return JSON.stringify(v);\r\n return String(v);\r\n}\r\n\r\nexport interface TopSignOptions {\r\n appSecret: string;\r\n params: Record<string, unknown>;\r\n /** 加密后 biz_content 的字符串(明文 base64 之后) */\r\n cipherText?: string;\r\n digest: Digest;\r\n}\r\n\r\n/** TOP 风格签名 */\r\nexport function signTop(opts: TopSignOptions): string {\r\n const bizStr = buildSortedParams(opts.params, false);\r\n // 拼接规则:bizStr + secret + cipherText(可选)\r\n const source = bizStr + opts.appSecret + (opts.cipherText ?? '');\r\n return opts.digest.sign(source, opts.appSecret);\r\n}\r\n\r\n/** TOP 风格验签 */\r\nexport function verifyTop(opts: TopSignOptions & { signature: string }): boolean {\r\n return opts.digest.verify(opts.signature, (() => {\r\n const bizStr = buildSortedParams(opts.params, false);\r\n return bizStr + opts.appSecret + (opts.cipherText ?? '');\r\n })(), opts.appSecret);\r\n}\r\n\r\n/** 计算待签名字符串(供调试) */\r\nexport function buildTopSignSource(params: Record<string, unknown>, appSecret: string, cipherText?: string): string {\r\n return buildSortedParams(params, false) + appSecret + (cipherText ?? '');\r\n}\r\n","/**\r\n * TOP 协议策略\r\n *\r\n * 关键字段:\r\n * - method: API 方法名,如 \"taobao.user.get\"\r\n * - app_key: 应用标识\r\n * - session?: 用户会话 token\r\n * - timestamp: 时间戳(格式 \"yyyy-MM-dd HH:mm:ss\",这里简化为 ms)\r\n * - v: 协议版本,默认 \"2.0\"\r\n * - sign_method: 摘要算法,如 \"hmac-sha256\"\r\n * - sign: 业务参数签名\r\n * - format?: 响应格式 \"json\" | \"xml\",默认 json\r\n * - biz_content: 业务参数(JSON 字符串,**整体加密后 base64**)\r\n * - cipher: biz_content 使用的加密算法\r\n * - digest: sign_method 的别名\r\n *\r\n * 业务参数签名拼接规则(由 signer.ts 实现):\r\n * signSource = sortedBizParams + appSecret + cipherText\r\n * sign = digest(signSource, appSecret)\r\n */\r\n\r\nimport * as nodeCrypto from 'crypto';\r\nimport type {\r\n ProtocolStrategy, ProtocolRequestInput, ProtocolClientContext, ProtocolServerContext, ProtocolVerifyResult,\r\n} from '../base';\r\nimport type { CipherAlgorithm, DigestAlgorithm } from '../../algorithms/types';\r\nimport { getCipher, getDigest } from '../../algorithms/registry';\r\nimport { SecureError, ErrorCode } from '../../errors';\r\nimport { signTop, verifyTop } from './signer';\r\n\r\nconst PROTOCOL = 'top';\r\n\r\nexport const topProtocol: ProtocolStrategy = {\r\n kind: PROTOCOL,\r\n\r\n async buildRequest(input, ctx) {\r\n const cipherName = (input.cipher || 'aes-256-gcm') as CipherAlgorithm;\r\n const digestName = (input.digest || 'hmac-sha256') as DigestAlgorithm;\r\n const cipher = getCipher(cipherName);\r\n const digest = getDigest(digestName);\r\n\r\n // 1. 业务参数 → JSON\r\n const bizJson = JSON.stringify(input.biz);\r\n // 2. 加密 biz_content\r\n const r = cipher.encrypt(Buffer.from(bizJson, 'utf-8'), {\r\n key: ctx.encryptionKey,\r\n rsaPublicKeyPem: ctx.rsaPublicKeyPem,\r\n });\r\n const cipherText = r.data.toString('base64');\r\n const iv = r.iv.toString('base64');\r\n const tag = r.tag?.toString('base64');\r\n const encryptedKey = r.encryptedKey?.toString('base64');\r\n\r\n // 3. 系统参数\r\n const sysParams: Record<string, unknown> = {\r\n method: input.path, // TOP 风格:path 实际是 method 名\r\n app_key: ctx.appKey,\r\n timestamp: Date.now(),\r\n v: '2.0',\r\n sign_method: digestName,\r\n cipher: cipherName,\r\n format: 'json',\r\n };\r\n if (input.session) sysParams.session = input.session;\r\n\r\n // 4. 签名(参与签名:业务参数 + cipherText)\r\n const paramsForSign: Record<string, unknown> = {\r\n ...input.biz,\r\n method: sysParams.method,\r\n app_key: sysParams.appKey,\r\n timestamp: sysParams.timestamp,\r\n v: sysParams.v,\r\n sign_method: sysParams.sign_method,\r\n cipher: sysParams.cipher,\r\n };\r\n if (input.session) paramsForSign.session = input.session;\r\n\r\n const signature = signTop({\r\n appSecret: ctx.appSecret,\r\n params: paramsForSign,\r\n cipherText,\r\n digest,\r\n });\r\n\r\n // 5. 信封\r\n const envelope: Record<string, unknown> = {\r\n protocol: PROTOCOL,\r\n ...sysParams,\r\n biz_content: cipherText,\r\n sign: signature,\r\n };\r\n if (iv) envelope.iv = iv;\r\n if (tag) envelope.authTag = tag;\r\n if (encryptedKey) envelope.encrypted_key = encryptedKey;\r\n return envelope;\r\n },\r\n\r\n async parseAndVerify(raw, ctx) {\r\n const appKey = (raw.app_key as string) || ctx.app.appKey;\r\n if (!appKey) throw new SecureError(ErrorCode.MISSING_APP_KEY, 'TOP 协议缺少 app_key');\r\n const method = raw.method as string;\r\n if (!method) throw new SecureError(ErrorCode.MISSING_METHOD, 'TOP 协议缺少 method');\r\n const cipherName = (raw.cipher as CipherAlgorithm) || 'aes-256-gcm';\r\n const digestName = (raw.sign_method as DigestAlgorithm) || 'hmac-sha256';\r\n\r\n // 白名单校验\r\n if (ctx.app.allowedCiphers?.length && !ctx.app.allowedCiphers.includes(cipherName)) {\r\n throw new SecureError(ErrorCode.UNSUPPORTED_CIPHER, `app ${appKey} 不允许 cipher: ${cipherName}`);\r\n }\r\n if (ctx.app.allowedDigests?.length && !ctx.app.allowedDigests.includes(digestName)) {\r\n throw new SecureError(ErrorCode.SIGN_METHOD_NOT_ALLOWED, `app ${appKey} 不允许 sign_method: ${digestName}`);\r\n }\r\n\r\n // 时间戳 / nonce\r\n const timestamp = Number(raw.timestamp);\r\n validateTimestamp(timestamp, ctx.requestWindowMs);\r\n await checkNonce(ctx.nonceStore, (raw.nonce as string) || `top:${method}:${timestamp}`, ctx.requestWindowMs);\r\n\r\n // 业务参数\r\n const bizContent = raw.biz_content as string;\r\n if (!bizContent) throw new SecureError(ErrorCode.INVALID_PAYLOAD, 'TOP 协议缺少 biz_content');\r\n const iv = raw.iv as string | undefined;\r\n const tag = raw.authTag as string | undefined;\r\n const encryptedKey = raw.encrypted_key as string | undefined;\r\n\r\n // 解密 biz_content\r\n const cipher = getCipher(cipherName);\r\n const plain = cipher.decrypt(Buffer.from(bizContent, 'base64'), {\r\n key: ctx.encryptionKey,\r\n iv: iv ? Buffer.from(iv, 'base64') : Buffer.alloc(0),\r\n tag: tag ? Buffer.from(tag, 'base64') : undefined,\r\n encryptedKey: encryptedKey ? Buffer.from(encryptedKey, 'base64') : undefined,\r\n rsaPrivateKeyPem: ctx.rsaPrivateKeyPem,\r\n });\r\n const biz = JSON.parse(plain.toString('utf-8'));\r\n\r\n // 验签\r\n const digest = getDigest(digestName);\r\n const paramsForSign: Record<string, unknown> = {\r\n ...biz,\r\n method, app_key: appKey, timestamp, v: raw.v, sign_method: digestName, cipher: cipherName,\r\n };\r\n if (raw.session) paramsForSign.session = raw.session;\r\n const ok = verifyTop({\r\n appSecret: ctx.app.appSecret,\r\n params: paramsForSign,\r\n cipherText: bizContent,\r\n digest,\r\n signature: raw.sign as string,\r\n });\r\n if (!ok) throw new SecureError(ErrorCode.SIGNATURE_MISMATCH, 'TOP 协议签名验证失败');\r\n\r\n return {\r\n appKey, method,\r\n path: method,\r\n session: raw.session as string | undefined,\r\n biz,\r\n };\r\n },\r\n\r\n async buildResponse(biz, ctx) {\r\n const cipherName = 'aes-256-gcm';\r\n const digestName = 'hmac-sha256';\r\n const cipher = getCipher(cipherName);\r\n const digest = getDigest(digestName);\r\n\r\n const r = cipher.encrypt(Buffer.from(JSON.stringify(biz), 'utf-8'), { key: ctx.encryptionKey });\r\n const cipherText = r.data.toString('base64');\r\n const iv = r.iv.toString('base64');\r\n const tag = r.tag?.toString('base64');\r\n const timestamp = Date.now();\r\n const paramsForSign: Record<string, unknown> = {\r\n app_key: ctx.app.appKey, timestamp, sign_method: digestName, cipher: cipherName,\r\n };\r\n const sign = signTop({ appSecret: ctx.app.appSecret, params: paramsForSign, cipherText, digest });\r\n return {\r\n protocol: PROTOCOL,\r\n app_key: ctx.app.appKey,\r\n timestamp,\r\n v: '2.0',\r\n sign_method: digestName,\r\n cipher: cipherName,\r\n biz_content: cipherText,\r\n iv,\r\n authTag: tag,\r\n sign,\r\n };\r\n },\r\n};\r\n\r\nfunction validateTimestamp(ts: number, windowMs: number) {\r\n const now = Date.now();\r\n if (!ts) throw new SecureError(ErrorCode.INVALID_TIMESTAMP, '时间戳无效');\r\n if (ts > now + 5000) throw new SecureError(ErrorCode.INVALID_TIMESTAMP, '时间戳来自未来');\r\n if (now - ts > windowMs) throw new SecureError(ErrorCode.TIMESTAMP_EXPIRED, '请求已过期');\r\n}\r\n\r\nasync function checkNonce(store: ProtocolServerContext['nonceStore'], nonce: string, windowMs: number) {\r\n if (!store) return;\r\n const ttl = Math.ceil((windowMs * 2) / 1000);\r\n const r = await store.set(`nonce:${nonce}`, '1', 'EX', ttl, 'NX');\r\n if (r === null) throw new SecureError(ErrorCode.NONCE_REUSED, 'nonce 已被使用');\r\n}\r\n","/**\r\n * 协议注册表\r\n */\r\n\r\nimport type { ProtocolKind, ProtocolStrategy } from './base';\r\nimport { SecureError, ErrorCode } from '../errors';\r\nimport { customProtocol } from './custom';\r\nimport { topProtocol } from './top';\r\n\r\nexport const protocolRegistry = new Map<ProtocolKind, ProtocolStrategy>([\r\n ['custom', customProtocol],\r\n ['top', topProtocol],\r\n]);\r\n\r\nexport function getProtocol(kind: ProtocolKind): ProtocolStrategy {\r\n const p = protocolRegistry.get(kind);\r\n if (!p) throw new SecureError(ErrorCode.PROTOCOL_NOT_FOUND, `Unsupported protocol: ${kind}`);\r\n return p;\r\n}\r\n\r\n/** 探测协议:优先用 envelope.protocol,否则用默认 */\r\nexport function pickProtocol(envelope: Record<string, unknown>, defaultKind: ProtocolKind = 'top'): ProtocolStrategy {\r\n const k = (envelope.protocol as ProtocolKind) || defaultKind;\r\n return getProtocol(k);\r\n}\r\n"],"mappings":"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A,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAC3E;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAA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","names":["nodeCrypto","nodeCrypto","nodeCrypto","META","pkcs7Pad","pkcs7Unpad","META","nodeCrypto","META","nodeCrypto","META_256","nodeCrypto","META","rotl","nodeCrypto","PROTOCOL","validateTimestamp","checkNonce","fp"]}
|