前后端接口加密,数字签名 您所在的位置:网站首页 接口加时间戳 前后端接口加密,数字签名

前后端接口加密,数字签名

2023-07-10 14:35| 来源: 网络整理| 查看: 265

一、前言

        最近查阅项目日志时,我发现了一些奇怪的请求,比如有人访问了 "/robot.txt"。由于之前了解过渗透测试,我猜测可能有人使用自动扫描工具尝试对我的项目进行扫描。

        为了解决这个问题,我考虑了一些解决思路。首先,在前端方面,我打算对接口进行加密。具体做法是统一拦截所有的http请求,在请求头中添加时间戳。然后,我会将这个时间戳与当前的实时时间进行对比,如果超过了我所定义的时间范围,就会抛出错误。此外,我还会利用哈希算法,结合时间戳和http请求的body或params,生成一个秘钥。这样,在后端接收到请求后,我们可以通过解密和验证数字签名,确保请求的完整性和合法性。

二、前端处理

1、首先定义一个js工具函数,利用params, timestamp, secretKey,生成秘钥,详细代码如下:

import crypto from 'crypto'; export function generateSign(params, timestamp, secretKey) { let paramStr = ''; if (params !== undefined) { paramStr = JSON.stringify(params); } paramStr += String(timestamp); paramStr += secretKey; // console.log("加密前组装",paramStr) console.log("加密后结果",crypto.createHash('sha256').update(paramStr).digest('hex')) return crypto.createHash('sha256').update(paramStr).digest('hex'); }

2、需要在vue项目的请求拦截器添加处理之后的秘钥,详情如下:

import { generateSign } from './sign.js' const secretKey = 'your-secret-key'; class Http { constructor() { this.http = axios.create({ baseURL: backURL, timeout:100000 }) // 设置拦截器,用来添加JWT Token的 this.http.interceptors.request.use(config => { const token = sessionStorage.getItem("token"); if (token && token != 'undefined') { config.headers.common.Authorization = "Token " + token // 获取当前时间戳 return addSignAndTimestamp(config) } return addSignAndTimestamp(config) },error =>{ return Promise.reject(error) }) function addSignAndTimestamp(config) { const timestamp = Date.now(); let sign; if (config.method === 'post' || config.method === 'put') { sign = generateSign(config.data, timestamp, secretKey); } else { sign = generateSign(config.params, timestamp, secretKey); } config.headers['X-Timestamp'] = timestamp; config.headers['X-Sign'] = sign; return config; } } } 三、后端处理

1、前端使用了hash生成秘钥,在后端也需要同样的算法生成秘钥。

import hashlib import json def generate_sign(params, timestamp, secret_key): param_str = json.dumps(params, separators=(',', ':'), ensure_ascii=False) if params and params != {} else '' param_str = f"{param_str}{timestamp}{secret_key}" hash_obj = hashlib.sha256(param_str.encode()) return hash_obj.hexdigest()

2、后端django可以利用中间件在视图层获取到请求之前进行处理

首先,自己定义中间件的内容,尤其需要注意secret_key 需要前后端保持一致。

import json import time import hashlib from django.http import HttpResponseBadRequest from sso.sign import generate_sign class SignatureMiddleware: def __init__(self, get_response): self.get_response = get_response self.secret_key = 'your-secret-key' def __call__(self, request): # # 在请求头中获取签名和时间戳 timestamp = request.META.get('HTTP_X_TIMESTAMP') sign = request.META.get('HTTP_X_SIGN') if not timestamp or not sign: # 如果请求头中没有签名或时间戳,返回错误响应 return HttpResponseBadRequest('Missing signature or timestamp') # 构造签名参数 if requesthod == 'GET': params = request.GET.dict() elif requesthod == 'POST': params = convert_request_body(request.body) elif requesthod == 'PUT': params = convert_request_body(request.body) elif requesthod == 'DELETE': params = convert_request_body(request.body) else: # 对于其他请求方法,可以根据需要自行处理 return HttpResponseBadRequest('no support method') # 根据请求参数、时间戳和密钥生成签名 expected_sign = generate_sign(params, timestamp, self.secret_key) # 验证签名是否正确 if sign != expected_sign: return HttpResponseBadRequest('Invalid signature') # 验证时间戳是否过期 now = int(time.time() * 1000) if abs(now - int(timestamp)) > 3 * 60 * 1000: # 时间戳有效期为 3 分钟 return HttpResponseBadRequest('Expired timestamp') # 如果签名和时间戳均合法,则继续处理请求 response = self.get_response(request) return response def convert_request_body(request_body): # 解码请求体字节,如果为空则返回空字典 body_str = request_body.decode('utf-8') if request_body else "" # 将解码后的字符串转换为字典,如果为空则返回空字典 params = json.loads(body_str) if body_str else "" return params

3、在项目的 settings.py添加中间件即可

MIDDLEWARE = [ 'sso.SignatureMiddleware.SignatureMiddleware' #自定义的中间件 ] 四、总结

        通过引入时间戳超时机制和哈希算法数字签名技术,我们有效地防止了重放攻击和请求篡改的风险。这些安全措施不仅保护了项目的机密性和完整性,也提升了用户对项目的信任度。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有