const CryptoJS = require('crypto-js') const SIGNATURE_SECRET = 'NovalonManageSystemSecretKey2026' /** * 生成 HMAC-SHA256 签名 */ function generateSignature(method, path, query, body, timestamp, nonce) { const stringToSign = [method, path, query || '', body || '', String(timestamp), nonce].join('\n') const signature = CryptoJS.HmacSHA256(stringToSign, SIGNATURE_SECRET) return CryptoJS.enc.Base64.stringify(signature) } /** * 生成随机 nonce */ function generateNonce() { const timestamp = Date.now().toString(36) const randomPart = Math.random().toString(36).substring(2, 15) return timestamp + '-' + randomPart } /** * 从 URL 解析 path 和 query */ function parseUrl(url) { if (url.startsWith('http://') || url.startsWith('https://')) { const withoutProtocol = url.substring(url.indexOf('://') + 3) const pathStart = withoutProtocol.indexOf('/') if (pathStart === -1) return { path: '/', query: '' } const pathAndQuery = withoutProtocol.substring(pathStart) const queryIndex = pathAndQuery.indexOf('?') if (queryIndex === -1) return { path: pathAndQuery, query: '' } return { path: pathAndQuery.substring(0, queryIndex), query: pathAndQuery.substring(queryIndex + 1) } } const queryIndex = url.indexOf('?') if (queryIndex === -1) return { path: url, query: '' } return { path: url.substring(0, queryIndex), query: url.substring(queryIndex + 1) } } /** * 生成签名请求头 */ function generateSignatureHeaders(method, url, body) { const timestamp = Date.now() const nonce = generateNonce() const { path, query } = parseUrl(url) const bodyStr = body ? (typeof body === 'string' ? body : JSON.stringify(body)) : '' const signature = generateSignature(method.toUpperCase(), path, query, bodyStr, timestamp, nonce) return { 'X-Signature': signature, 'X-Timestamp': String(timestamp), 'X-Nonce': nonce } } module.exports = { generateSignatureHeaders }