// ============================================ // 加密解密工具 // ============================================ // 处理微信服务号的消息加密、解密和签名验证 // 微信使用 AES-256-CBC 加密算法和 SHA-1 签名算法 /** * 验证签名参数接口 * @property token - 微信服务号配置的 Token * @property timestamp - 时间戳 * @property nonce - 随机数 * @property encrypt - 加密的消息内容 * @property signature - 微信生成的签名,用于验证消息来源 */ export interface VerifySignatureParams { token: string; timestamp: string; nonce: string; encrypt: string; signature: string; } /** * 解密消息参数接口 * @property encodingAESKey - 微信服务号配置的 EncodingAESKey(43位字符) * @property receiveId - 接收方 ID(通常是服务号的原始 ID) * @property encrypt - 加密的消息内容(Base64 编码) */ export interface DecryptMessageParams { encodingAESKey: string; receiveId: string; encrypt: string; } /** * 验证微信消息签名 * @param params - 签名验证参数 * @returns 签名是否有效 * @description * 验证流程: * 1. 将 token、timestamp、nonce、encrypt 按字典序排序 * 2. 拼接成字符串 * 3. 进行 SHA-1 哈希 * 4. 与微信提供的 signature 比对 * * **注意:当前为简化实现,生产环境需要实现真实的 SHA-1 签名验证** */ export const verifySignature = (params: VerifySignatureParams): boolean => { // TODO: 实现真实的签名验证逻辑 // 参考算法: // const arr = [params.token, params.timestamp, params.nonce, params.encrypt].sort(); // const str = arr.join(''); // const hash = crypto.createHash('sha1').update(str).digest('hex'); // return hash === params.signature; console.log("[wechat-access] 验证签名参数:", params); return true; // 简化实现,直接返回 true }; /** * 解密微信消息 * @param params - 解密参数 * @returns 解密后的明文消息(JSON 字符串) * @description * 解密流程: * 1. 将 Base64 编码的 encrypt 解码为二进制 * 2. 使用 AES-256-CBC 算法解密(密钥由 encodingAESKey 派生) * 3. 去除填充(PKCS7) * 4. 提取消息内容(格式:随机16字节 + 4字节消息长度 + 消息内容 + receiveId) * 5. 验证 receiveId 是否匹配 * * **注意:当前为简化实现,返回模拟数据,生产环境需要实现真实的 AES 解密** */ export const decryptMessage = (params: DecryptMessageParams): string => { // TODO: 实现真实的解密逻辑 // 参考算法: // const key = Buffer.from(params.encodingAESKey + '=', 'base64'); // const iv = key.slice(0, 16); // const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv); // decipher.setAutoPadding(false); // let decrypted = Buffer.concat([decipher.update(params.encrypt, 'base64'), decipher.final()]); // // 去除 PKCS7 填充 // const pad = decrypted[decrypted.length - 1]; // decrypted = decrypted.slice(0, decrypted.length - pad); // // 提取消息内容 // const content = decrypted.slice(16); // const msgLen = content.readUInt32BE(0); // const message = content.slice(4, 4 + msgLen).toString('utf8'); // const receiveId = content.slice(4 + msgLen).toString('utf8'); // if (receiveId !== params.receiveId) throw new Error('receiveId mismatch'); // return message; console.log("[wechat-access] 解密参数:", params); // 返回模拟的解密结果(标准微信消息格式) return '{"msgtype":"text","Content":"Hello from 服务号","MsgId":"123456","FromUserName":"user001","ToUserName":"gh_test","CreateTime":1234567890}'; };