当前位置: 首页 > news >正文

Node.js 端的接口签名处理

用MD5,SHA256,HMAC-SHA256,RSA-SHA256签名算法
适用场景
博客或网站接口:保护评论提交,数据查询等接口,防止恶意请求或数据篡改
前后端分离项目:确保前端发送的请求未被中间人篡改,验证请求来源合法性
服务间调用:用于微服务,第三方API交互,通过签名确认调用方身份
爬虫攻防:作为反爬策略的一部分,只有正确生成签名的请求才能访问接口
const crypto = require('crypto');
const fs = require('fs');
class ApiSignature {
constructor(config = {}) {
this.appId = config.appId || '';
this.appSecret = config.appSecret || '';
this.privateKey = config.privateKey || '';
this.algo = config.algo || 'sha256';
}
generateNonce(length = 16) {
return crypto.randomBytes(length).toString('hex');
}
generateTimestamp() {
return Math.floor(Date.now() / 1000);
}
md5Sign(data, key = '') {
const signStr = data + key;
return crypto.createHash('md5').update(signStr, 'utf8').digest('hex');
}
sha256Sign(data, key = '') {
const signStr = data + key;
return crypto.createHash('sha256').update(signStr, 'utf8').digest('hex');
}
hmacSha256Sign(data, key) {
return crypto.createHmac('sha256', key).update(data, 'utf8').digest('hex');
}
hmacMd5Sign(data, key) {
return crypto.createHmac('md5', key).update(data, 'utf8').digest('hex');
}
rsaSha256Sign(data, privateKey) {
const sign = crypto.createSign('RSA-SHA256');
sign.update(data);
sign.end();
return sign.sign(privateKey, 'base64');
}
buildSignString(params) {
const sortedKeys = Object.keys(params).sort();
const pairs = [];

    for (const key of sortedKeys) {const value = params[key];if (value !== null && value !== undefined && value !== '') {pairs.push(`${key}=${value}`);}}return pairs.join('&');
}
generateSignature(params, method = 'sha256', secret = this.appSecret) {const signString = this.buildSignString(params);switch (method.toLowerCase()) {case 'md5':return this.md5Sign(signString, secret);case 'sha256':return this.sha256Sign(signString, secret);case 'hmac_sha256':return this.hmacSha256Sign(signString, secret);case 'hmac_md5':return this.hmacMd5Sign(signString, secret);case 'rsa_sha256':return this.rsaSha256Sign(signString, this.privateKey);default:throw new Error(`Unsupported signature method: ${method}`);}
}
buildSignedParams(params = {}, options = {}) {const {method = 'sha256',includeAppId = true,includeTimestamp = true,includeNonce = true,secret = this.appSecret,version = '1.0'} = options;const signedParams = { ...params };// 添加应用IDif (includeAppId && this.appId) {signedParams.app_id = this.appId;}// 添加时间戳if (includeTimestamp) {signedParams.timestamp = this.generateTimestamp();}// 添加随机字符串if (includeNonce) {signedParams.nonce_str = this.generateNonce();}// 添加版本号signedParams.version = version;// 生成签名signedParams.sign = this.generateSignature(signedParams, method, secret);return signedParams;
}
verifySignature(params, receivedSign, method = 'sha256', secret = this.appSecret) {const calculatedSign = this.generateSignature(params, method, secret);return calculatedSign === receivedSign;
}
buildAuthorizationHeader(params = {}, method = 'sha256') {const signedParams = this.buildSignedParams(params, { method });const token = Buffer.from(JSON.stringify(signedParams)).toString('base64');return `Bearer ${token}`;
}
parseAuthorizationHeader(authHeader) {if (!authHeader.startsWith('Bearer ')) {return null;}try {const token = authHeader.substring(7);const decoded = Buffer.from(token, 'base64').toString('utf8');return JSON.parse(decoded);} catch (error) {return null;}
}

}
if (require.main === module) {
// 初始化签名器
const signature = new ApiSignature({
appId: 'your_app_id',
appSecret: 'your_app_secret',
privateKey: 'your_rsa_private_key'
});
console.log('\n=== 签名 ===');
const complexParams = {
name: '南黎w7y',
age: 20,
hobbies: ['阅读', '游泳', ' 音乐', ' 旅行', ' 看书', ' 打篮球'],
profile: {
city: '西安',
occupation: '程序员'
}
};
// 将复杂对象转为json字符串进行签名
const jsonParams = {};
for (const [key, value] of Object.entries(complexParams)) {
jsonParams[key] = JSON.stringify(value);
}
const signedParams3 = signature.buildSignedParams(jsonParams,
{
method: 'sha256'
});
console.log('签名:', signedParams3.sign);
}
module.exports = ApiSignature;

http://www.jsqmd.com/news/48583/

相关文章:

  • ABC433 解题报告
  • 20232402 2025-2026-1 《网络与系统攻防技术》实验六实验报告
  • P2949 [USACO09OPEN] Work Scheduling G 题解
  • the success of Japan
  • 预训练的卷积神经网络与普通卷积神经网络有什么区别
  • 人工智能之数据分析 numpy:第九章 数组运算
  • Faster R-CNN中的Backbone,输入图片时,是标注过的图片吗
  • 赫尔默特变化 A=0的情况
  • 关于tarjan的一些感性理解
  • java linux tomcat
  • 20232411 2024-2025-1 《网络与系统攻防技术》实验六实验报告
  • 实用指南:机器人描述文件xacro(urdf扩展)
  • 代码随想录Day17_二叉树
  • 人工智能之数据分析 numpy:第七章 数组迭代排序筛选
  • AE文字动画
  • 2025/11/23-Listening to music most days could lower dementia risks for older adults, study suggests
  • 完整教程:设计模式的底层原理——解耦
  • windows11资源管理器桌面文件夹从中文“桌面”变为应为“Desktop”的恢复方法
  • Oracle数据库核心操作完全手册:运维、开发与调优必备
  • 2025/11/25
  • 完整教程:单体架构中的事件驱动架构:Java应用程序的渐进式重构
  • 2025/11/26
  • TRUG如何验证随机性
  • 【网络】在windows下,使用自带的ftp服务器,并添加账户 - 指南
  • 实用指南:JVM篇:一文读懂JVM:工作原理之核心技术解析
  • 2025年西北地区软化水设备厂家选择指南,陕西、甘肃、新疆、宁夏四省首选西安紫云,行业口碑品质靠谱推荐
  • java geotiff的空间索引如何构建
  • java for linux 安装
  • 【OI 复健计划】板子复习
  • 时间即生命 梁实秋