const { sm4 } = require('sm-crypto'); const appId = process.env.CONFIG_ZYB_YB_APPID; const appSecret = process.env.CONFIG_ZYB_YB_SECRET; // 检查环境变量是否配置 function checkEnvConfig() { if (!appId || !appSecret) { const error = new Error( '加密配置未设置:缺少环境变量 CONFIG_ZYB_YB_APPID 或 CONFIG_ZYB_YB_SECRET。\n' + '请确保在环境配置文件中设置了这些变量。' ); error.code = 'ENV_CONFIG_MISSING'; throw error; } if (appId.length < 16) { const error = new Error('CONFIG_ZYB_YB_APPID 长度必须至少16个字符'); error.code = 'ENV_CONFIG_INVALID'; throw error; } } class Sm4Util { static encryptDataForSm3(plainStr) { checkEnvConfig(); return this.encryptData(plainStr, appId, appSecret); } static encryptData(plainStr, appId, appSecret) { // 取appId的前16个字符作为第一个密钥(对应Java逻辑) const firstKey = appId.substring(0, 16); // 将字符串转换为32位十六进制密钥(SM4要求) const firstKeyHex = Buffer.from(firstKey, 'utf8').toString('hex').padEnd(32, '0').substring(0, 32); // 使用第一个密钥加密appSecret,得到十六进制字符串(对应Java的encryptHex) const encKeyHex = sm4.encrypt(appSecret, firstKeyHex,); // 取加密结果的前16个字符作为新密钥(对应Java逻辑:newKey = encKey.substring(0, 16)) const newKey = encKeyHex.substring(0, 16); // 将新密钥转换为32位十六进制密钥(SM4要求) const newKeyHex = Buffer.from(newKey, 'utf8').toString('hex').padEnd(32, '0').substring(0, 32); // 使用新密钥加密明文 const encrypted = sm4.encrypt(plainStr, newKeyHex); // 转换为URL安全的base64 const buffer = Buffer.from(encrypted, 'hex'); const base64 = buffer.toString('base64'); return base64.replace(/\+/g, '-').replace(/\//g, '_'); } static decryptDataForSm3(encryptStr) { checkEnvConfig(); return this.decryptData(encryptStr, appId, appSecret); } static decryptData(encryptStr, appId, appSecret) { // 相同的密钥生成逻辑 const firstKey = appId.substring(0, 16); // 将字符串转换为32位十六进制密钥(SM4要求) const firstKeyHex = Buffer.from(firstKey, 'utf8').toString('hex').padEnd(32, '0').substring(0, 32); const encKeyHex = sm4.encrypt(appSecret, firstKeyHex); // 取加密结果的前16个字符作为新密钥(对应Java逻辑:newKey = encKey.substring(0, 16)) const newKey = encKeyHex.substring(0, 16); // 将新密钥转换为32位十六进制密钥(SM4要求) const newKeyHex = Buffer.from(newKey, 'utf8').toString('hex').padEnd(32, '0').substring(0, 32); // 处理URL安全的base64 let base64Str = encryptStr.replace(/-/g, '+').replace(/_/g, '/'); const padding = 4 - (base64Str.length % 4); if (padding !== 4) { base64Str += '='.repeat(padding); } const buffer = Buffer.from(base64Str, 'base64'); const hexStr = buffer.toString('hex'); return sm4.decrypt(hexStr, newKeyHex); } } module.exports = Sm4Util;