当前位置:   article > 正文

前后端接口加密,数字签名_怎么对开发的接口进行加密

怎么对开发的接口进行加密

一、前言

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

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

二、前端处理

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

  1. import crypto from 'crypto';
  2. export function generateSign(params, timestamp, secretKey) {
  3. let paramStr = '';
  4. if (params !== undefined) {
  5. paramStr = JSON.stringify(params);
  6. }
  7. paramStr += String(timestamp);
  8. paramStr += secretKey;
  9. // console.log("加密前组装",paramStr)
  10. console.log("加密后结果",crypto.createHash('sha256').update(paramStr).digest('hex'))
  11. return crypto.createHash('sha256').update(paramStr).digest('hex');
  12. }

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

  1. import { generateSign } from './sign.js'
  2. const secretKey = 'your-secret-key';
  3. class Http {
  4. constructor() {
  5. this.http = axios.create({
  6. baseURL: backURL,
  7. timeout:100000
  8. })
  9. // 设置拦截器,用来添加JWT Token的
  10. this.http.interceptors.request.use(config => {
  11. const token = sessionStorage.getItem("token");
  12. if (token && token != 'undefined') {
  13. config.headers.common.Authorization = "Token " + token
  14. // 获取当前时间戳
  15. return addSignAndTimestamp(config)
  16. }
  17. return addSignAndTimestamp(config)
  18. },error =>{
  19. return Promise.reject(error)
  20. })
  21. function addSignAndTimestamp(config) {
  22. const timestamp = Date.now();
  23. let sign;
  24. if (config.method === 'post' || config.method === 'put') {
  25. sign = generateSign(config.data, timestamp, secretKey);
  26. } else {
  27. sign = generateSign(config.params, timestamp, secretKey);
  28. }
  29. config.headers['X-Timestamp'] = timestamp;
  30. config.headers['X-Sign'] = sign;
  31. return config;
  32. }
  33. }
  34. }

三、后端处理

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

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

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

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

  1. import json
  2. import time
  3. import hashlib
  4. from django.http import HttpResponseBadRequest
  5. from sso.sign import generate_sign
  6. class SignatureMiddleware:
  7. def __init__(self, get_response):
  8. self.get_response = get_response
  9. self.secret_key = 'your-secret-key'
  10. def __call__(self, request):
  11. # # 在请求头中获取签名和时间戳
  12. timestamp = request.META.get('HTTP_X_TIMESTAMP')
  13. sign = request.META.get('HTTP_X_SIGN')
  14. if not timestamp or not sign:
  15. # 如果请求头中没有签名或时间戳,返回错误响应
  16. return HttpResponseBadRequest('Missing signature or timestamp')
  17. # 构造签名参数
  18. if request.method == 'GET':
  19. params = request.GET.dict()
  20. elif request.method == 'POST':
  21. params = convert_request_body(request.body)
  22. elif request.method == 'PUT':
  23. params = convert_request_body(request.body)
  24. elif request.method == 'DELETE':
  25. params = convert_request_body(request.body)
  26. else:
  27. # 对于其他请求方法,可以根据需要自行处理
  28. return HttpResponseBadRequest('no support method')
  29. # 根据请求参数、时间戳和密钥生成签名
  30. expected_sign = generate_sign(params, timestamp, self.secret_key)
  31. # 验证签名是否正确
  32. if sign != expected_sign:
  33. return HttpResponseBadRequest('Invalid signature')
  34. # 验证时间戳是否过期
  35. now = int(time.time() * 1000)
  36. if abs(now - int(timestamp)) > 3 * 60 * 1000: # 时间戳有效期为 3 分钟
  37. return HttpResponseBadRequest('Expired timestamp')
  38. # 如果签名和时间戳均合法,则继续处理请求
  39. response = self.get_response(request)
  40. return response
  41. def convert_request_body(request_body):
  42. # 解码请求体字节,如果为空则返回空字典
  43. body_str = request_body.decode('utf-8') if request_body else ""
  44. # 将解码后的字符串转换为字典,如果为空则返回空字典
  45. params = json.loads(body_str) if body_str else ""
  46. return params

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

  1. MIDDLEWARE = [
  2. 'sso.SignatureMiddleware.SignatureMiddleware' #自定义的中间件
  3. ]

四、总结

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/589303
推荐阅读
相关标签
  

闽ICP备14008679号