http数据传输确保完整性和保密性整流程方案(含源码)

在这里插入图片描述
往期文章回顾

  • 【深度学习】
    • 【深度学习】物体检测/分割/追踪/姿态估计/图像分类检测演示系统【含源码】
    • 【深度学习】YOLOV8数据标注及模型训练方法整体流程介绍及演示
    • 【深度学习】行人跌倒行为检测软件系统
    • 【深度学习】火灾检测软件系统
    • 【深度学习】吸烟行为检测软件系统
    • 【深度学习】数竹签演示软件系统
    • 【深度学习】菜品目标检测软件系统
  • 【爬虫】
    • 爬取A股数据写入数据库(一)
    • 爬取A股数据写入数据库(二)
    • 爬取股票历史K线数据写入数据库(三)
    • 爬取股票数据写入数据库并显示(四)
  • 【QT】
    • QT5集成FTP实现文件及文件夹的下载
    • QT集成开源日志库示例
  • 【Python源码加密】
    • python源码加密之Cython方案简单示例
    • Cython针对python工程多层级目录处理办法
  • 【数据安全】
    • http服务网络请求如何确保数据安全(含python示例源码)
    • http数据传输确保完整性和保密性全整流程方案(含源码)

1. 本文摘要

  • 当今数据安全越来越重要,http网络请求数据安全加强要求是为了保护公民的隐私和数据安全,防范日益复杂的网络攻击,确保电子商务和在线服务的可靠性,并遵守相关法律法规。
  • 上一篇文章中,结合我参与的项目,粗略描述了在http网络请求中如何做到数据安全,并附了一些源码
  • 本文主要介绍"http请求中数据传输的完整性和传输过程中数据的保密性",这部分如何快速融入到已有的工程中,包括中间件转发,这样就可以无缝的连接到原来的项目中。
  • 本文仍然使用python flask来演示整个过程,并详细描述了这个过程的设计流程。
    本系统所涉及的源码已打包上传。
    文中源码文件【获取方式】:关注公众号:利哥AI实例探险
    给公众号发送 “http传输安全保密” 获取下载方式
    注意发送的关键词不能错,否则匹配不到对应资源,由于本人能力有限,难免有疏漏之处。

2. 项目中经常遇到的问题及处理办法

  1. http协议数据传输,需采用校验码技术或密码技术保证重要数据在传输过程中的完整性。
  2. 鉴别信息及重要业务数据采用经国家密码主管部门认可的密码技术,保证其在传输过程中数据的保密性。

**数据的保密性:**使用国家密码管理局认可的对称加密算法(如AES)来确保数据的保密性
**数据的完整性:**可以使用HMAC(哈希消息认证码)来确保数据在传输过程中的完整性

**AES(Advanced Encryption Standard,高级加密标准)**是一种对称加密算法,用于保护数据的安全。它被广泛应用于各种数据加密场景,包括文件加密、网络通信加密等。AES以其高效性和强大的安全性成为现代数据加密的主流选择。
**哈希消息认证码(HMAC)**是一种用于验证消息完整性和真实性的技术。它结合了哈希函数和密钥,确保消息在传输过程中未被篡改。

3. 处理的问题及处理的流程

  1. 请求、接收双方共用aes key及hmac key。
  2. 请求方在发送请求时,对发送的原始数据进行aes加密,并计算哈希值
  3. 接收方在接到数据后,进行哈希值验证,以确保数据完整性,之后进行aes解密处理
  4. 接收方根据解密后的数据进行各种业务处理,在返回给请求方时,将返回数据进行aes加密,并计算哈希值
  5. 请求方在接收到请求返回时,进行哈希验证并进行aes解密,并进行业务处理
    在这里插入图片描述

4. 示例代码拆解

4.1 AES加解密

文章末尾会附带全部源码,以下为讲解
加密函数:

  • 输入:需要加密的原始数据字符串、aes key、随机生成的iv
  • 输出:加密后的数据串、随机生成的iv(供数据发送给接收方进行解密使用)

解密函数:

  • 输入:加密后的数据字符串、aes key、加密时的iv
  • 输出:解密后的原始数据
def generate_iv_16str() -> str:
    # 生成一个16字符长度的字符串作为IV
    return ''.join(random.choices(string.ascii_letters + string.digits, k=BLOCK_SIZE))

def encrypt_aes_str(plaintext, key, iv_str) -> Tuple[str, str]:
    # 将IV字符串转换为字节
    iv = iv_str.encode('utf-8')
    # 创建AES对象
    cipher = AES.new(key, AES.MODE_CBC, iv)
    # 加密并进行填充
    ciphertext = cipher.encrypt(pad(plaintext.encode('utf-8'), BLOCK_SIZE))
    # 将密文进行Base64编码
    encrypted_data = base64.b64encode(ciphertext).decode('utf-8')
    return encrypted_data, iv_str

def decrypt_aes_str(ciphertext: str, key: str, iv_str: str) -> str:
    # 将IV字符串转换为字节
    iv = iv_str.encode('utf-8')
    # 将密文解码为字节数组
    ciphertext = base64.b64decode(ciphertext)
    # 创建AES对象
    cipher = AES.new(key, AES.MODE_CBC, iv)
    # 解密并去除填充
    plaintext = unpad(cipher.decrypt(ciphertext), BLOCK_SIZE)
    return plaintext
    
if __name__ == '__main__':
    # 加密数据
    response_json = {"msg": "hello world"}
    data_str = json.dumps(response_json)
    # 加密
    encrypted_data, iv_str = encrypt_aes_str(data_str, SECRET_KEY, generate_iv_16str())
    # 解密
    body_str = decrypt_aes_str(encrypted_data, SECRET_KEY, iv_str)

4.2 哈希验证码生成

输入:加密后的字符串
输出:哈希验证码

# HMAC生成函数
def generate_hmac(data: str) -> str:
    return hmac.new(HMAC_KEY, data.encode('utf-8'), hashlib.sha256).hexdigest()

4.3 中间件处理

中间件前置处理函数:

  • 在中间件中解析数据,做数据完整性的哈希码认证
  • 在中间件中根据iv解析aes加密后的数据,再将这部分数据写入到中间件,供视图函数使用
  • 在视图函数中,进行业务处理
app = Flask(__name__)
app.before_request(before_request_func)
app.after_request(after_request_func)

def before_request_func():
    url_method = request.method.upper()
    url_str = request.url
    ip_address = request.remote_addr
    if 'OPTIONS' == url_method:
        return None
    if 'GET' == url_method:
        return None
    if 'POST' != url_method:
        return None    
    requestData = request.get_json()
    recv_iv = requestData.get('vector')
    recv_hmac = requestData.get('code')
    recv_data = requestData.get('data')
    body_str = decrypt_aes_str(recv_data, SECRET_KEY, recv_iv)
    # 验证HMAC
    calculate_hmac = generate_hmac(recv_data)
    if not hmac.compare_digest(calculate_hmac, recv_hmac):
        # 哈希消息验证码校验失败
        return jsonify({'error': 'HMAC verification failed'}), 400
    # 将修改后的数据重新赋值给request.data
    request._cached_data = body_str
    return None

中间件后置处理函数:

  • 视图函数处理完业务逻辑后,会将返回结果返回到中间件
  • 中间件需要对返回数据进行加密,再带上iv进行返回
app = Flask(__name__)
app.before_request(before_request_func)
app.after_request(after_request_func)
   
def after_request_func(response):
    url_str = request.url
    url_method = request.method.upper()
    if 'OPTIONS' == url_method:
        return response
    elif 'GET' == url_method:
        pass
    elif 'POST' == url_method:
        pass    
    response_json = response.get_json()
    # 加密数据
    data_str = json.dumps(response_json)
    encrypted_data, iv_str = encrypt_aes_str(data_str, SECRET_KEY, generate_iv_16str())
    # 生成HMAC
    hmac_value = generate_hmac(encrypted_data)
    response_data = {
        'vector': iv_str,
        'data': encrypted_data,
        'code': hmac_value
    }
    response.data = json.dumps(response_data)
    response.mimetype = 'application/json'
    return response

5. 整体代码示例及逻辑

5.1 整体源码

from flask import Flask, request, jsonify
import hmac, hashlib, base64, json, string, random
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from typing import Tuple
app = Flask(__name__)
'''
AES
    CBC、BLOCK_SIZE=16、PKCS7填充
    使用Crypto.Util.Padding中的pad和unpad函数进行PKCS7填充和去填充。这里使用块大小BLOCK_SIZE(16字节, 即128位)进行填充。
    偏移量 (IV) 的长度是有要求的。
    对于AES (高级加密标准) 来说, IV的长度必须与AES的块大小相同, 这意味着IV的长度必须是16字节(128位),因为AES的块大小是128位。
'''
# 配置参数
# 共享密钥和HMAC密钥
SECRET_KEY = b'synjones2024zhc1'  # 16字节,即128位密钥  确保是16个字符, 避免引起不必要的异常
HMAC_KEY = b'synjones2024zhc2'  # 16字节,即128位HMAC密钥
BLOCK_SIZE = 16

def generate_iv_16str() -> str:
    # 生成一个16字符长度的字符串作为IV
    return ''.join(random.choices(string.ascii_letters + string.digits, k=BLOCK_SIZE))

def encrypt_aes_str(plaintext: str, key: str, iv_str: str) -> Tuple[str, str]:
    # 将IV字符串转换为字节
    iv = iv_str.encode('utf-8')
    # 创建AES对象
    cipher = AES.new(key, AES.MODE_CBC, iv)
    # 加密并进行填充
    ciphertext = cipher.encrypt(pad(plaintext.encode('utf-8'), BLOCK_SIZE))
    # 将密文进行Base64编码
    encrypted_data = base64.b64encode(ciphertext).decode('utf-8')
    return encrypted_data, iv_str

def decrypt_aes_str(ciphertext: str, key: str, iv_str: str) -> str:
    # 将IV字符串转换为字节
    iv = iv_str.encode('utf-8')
    # 将密文解码为字节数组
    ciphertext = base64.b64decode(ciphertext)
    # 创建AES对象
    cipher = AES.new(key, AES.MODE_CBC, iv)
    # 解密并去除填充
    plaintext = unpad(cipher.decrypt(ciphertext), BLOCK_SIZE)
    return plaintext

# HMAC生成函数
def generate_hmac(data: str) -> str:
    return hmac.new(HMAC_KEY, data.encode('utf-8'), hashlib.sha256).hexdigest()

# 定义中间件处理请求数据
def before_request_func():
    url_method = request.method.upper()
    url_str = request.url
    ip_address = request.remote_addr
    print(f'---------------------------------(starting:)server receive, method={url_method}, url={url_str}, remote_addr={ip_address}')
    if 'OPTIONS' == url_method:
        return None
    if 'GET' == url_method:
        return None
    if 'POST' != url_method:
        return None
    
    # 不需要任何验证的请求
    if url_str.find("/send") > 0 \
        or url_str.find("/receive") > 0 \
        or url_str.find("/login") > 0:
        return None
    
    requestData = request.get_json()
    recv_iv = requestData.get('vector')
    recv_hmac = requestData.get('code')
    recv_data = requestData.get('data')
    body_str = decrypt_aes_str(recv_data, SECRET_KEY, recv_iv)
    print('-------------body_str=', body_str)
    # 验证HMAC
    # calculate_hmac = generate_hmac(recv_data)
    # if not hmac.compare_digest(calculate_hmac, recv_hmac):
    #     # 哈希消息验证码校验失败
    #     return jsonify({'error': 'HMAC verification failed'}), 400
    # 将修改后的数据重新赋值给request.data
    request._cached_data = body_str
    return None

# 定义中间件处理响应数据
def after_request_func(response):
    url_str = request.url
    url_method = request.method.upper()
    if 'OPTIONS' == url_method:
        return response
    elif 'GET' == url_method:
        pass
    elif 'POST' == url_method:
        pass
    
        # 不需要任何验证的请求
    if url_str.find("/send") > 0 \
        or url_str.find("/receive") > 0 \
        or url_str.find("/login") > 0:
        return response
    
    response_json = response.get_json()
    # 加密数据
    data_str = json.dumps(response_json)
    encrypted_data, iv_str = encrypt_aes_str(data_str, SECRET_KEY, generate_iv_16str())
    # 生成HMAC
    hmac_value = generate_hmac(encrypted_data)
    response_data = {
        'vector': iv_str,
        'data': encrypted_data,
        'code': hmac_value
    }
    response.data = json.dumps(response_data)
    response.mimetype = 'application/json'
    return response

app.before_request(before_request_func)
app.after_request(after_request_func)

# 对json数据进行aes加密,并生成hmac
@app.route('/send', methods=['POST'])
def send_data():
    content = request.json
    data_str = json.dumps(content) # 将JSON对象序列化为字符串
    # 加密数据
    encrypted_data, iv_str = encrypt_aes_str(data_str, SECRET_KEY, generate_iv_16str())
    # 生成HMAC
    hmac_value = generate_hmac(encrypted_data)
    response = {
        'vector': iv_str,
        'data': encrypted_data,
        'code': hmac_value
    }
    return jsonify(response)

# 对aes加密的数据进行hmac验证,并解析aes加密的数据
@app.route('/receive', methods=['POST'])
def receive_data():
    content = request.json
    iv = content.get('vector')
    encrypted_data = content.get('data')
    received_hmac = content.get('code')

    # 验证HMAC
    expected_hmac = generate_hmac(encrypted_data)
    if not hmac.compare_digest(expected_hmac, received_hmac):
        return jsonify({'error': 'HMAC verification failed'}), 400

    # 解密数据
    decrypted_data_str = decrypt_aes_str(encrypted_data, SECRET_KEY, iv)
    if decrypted_data_str is None:
        return jsonify({'error': 'Decryption failed'}), 400

    # 将解密后的字符串反序列化为JSON对象
    decrypted_data = json.loads(decrypted_data_str)
    
    return jsonify({'data': decrypted_data})

@app.route('/encrypt', methods=['POST'])
def encrypt():
    j_data = json.loads(request.data)
    print('-------------路由接收:', j_data)
    return jsonify(j_data)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)

5.2 源码接口

  1. 对json进行加密(为了单独测试加密)
    在这里插入图片描述

  2. 对加密数据进行解析(为了单独测试解密)

在这里插入图片描述
3. 使用中间件流程(对应整体流程),即流程设计图中的流程,此接口是可以提供给请求端调用的接口
在这里插入图片描述

如果您觉得我分享的这些对您有用,请点击原文,关注我吧

原文地址:http数据传输确保完整性和保密性整流程方案(含源码)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/771491.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

rtpengine_mr12.0 基础建设容器运行

目录 Dockerfile rtpengine.conf 容器内编译安装 RTPEngine 正常提供功能 1. 启动RTPEngine服务 2. 删除 RTPEngine服务 3. 加载内核模块 检查所有进程是否正在运行 上传到仓库 博主wx:yuanlai45_csdn 博主qq:2777137742 后期会创建粉丝群&…

实验二 图像的代数运算

一、实验目的: 1.了解图像的算术运算在数字图像处理中的初步应用。 2.体会图像算术运算处理的过程和处理前后图像的变化。 二、实验内容: 1.图像的加法运算 图像相加一般用于对同一场景的多幅图像求平均效果&…

【QT】概述|对象树模型|两种控件模式|信号和槽|lambda

目录 什么是QT 特点 QT程序 main函数 QT按钮 纯代码模式 图形化模式 对象树模型 信号和槽 连接与断开 自动连接 断开连接 信号的发射 lambda表达式 基本语法 捕获列表 Lambda表达式用于信号与槽的连接 例如 什么是QT Qt是一个跨平台的C图形用户界面应用…

如何在TikTok上获得更多观看量:12个流量秘诀

TikTok作为热门海外社媒,在跨境出海行业中成为新兴的推广渠道,但你知道如何让你的TikTok赢得更多关注次数吗?如果您正在寻找增加 TikTok 观看次数的方法,接下来这12种策略,你需要一一做好! 1. 在内容中添加…

女性经济崛起,天润融通用客户感知挖掘市场潜力

每逢一年一度的国际妇女节,“女性”话题都会被郑重地讨论。 从消费市场上来说,最近几年女性群体正在拥有越来越大的影响力,甚至出现了“她经济”这样的专属词汇在最近几年被市场反复讨论。 毫无疑问,女性消费群体的崛起已经成为…

2.8亿东亚五国建筑数据分享

数据是GIS的血液! 我们现在为你分享东亚5国的2.8亿条建筑轮廓数据,该数据包括中国、日本、朝鲜、韩国和蒙古5个东亚国家完整、高质量的建筑物轮廓数据,你可以在文末查看领取方法。 数据介绍 虽然开源的全球的建筑数据已经有微软的建筑数据…

【android】【adb shell】写一个shell脚本,监听进程pid变化

前言 当前业务,需要写一个脚本,不断监视com.android.phone 进程是否异常死掉 脚本 #!/system/bin/sh last_pid"" current_pid"" while(true){current_pidps -A | grep com.android.phone | awk {print $2}if [ -n "$current…

大牛“私藏”宝刊,易Accept!中科院1区-Top,偏爱国人,2个月可录!

本周投稿推荐 SCI • 能源科学类,1.5-2.0(来稿即录25天) • 计算机类,2.0-3.0(纯正刊29天录用) EI • 各领域沾边均可(2天录用) CNKI • 7天录用-检索(急录友好&a…

职场办公受欢迎的电脑桌面便签,手机电脑同步的备忘录

在快节奏的职场生活中,有效的时间管理和信息记录变得尤为重要。为了帮助大家更好地应对工作挑战,好用的电脑桌面便签和手机电脑同步的备忘录,好用便签应运而生,成为了当前职场办公中的得力助手。 好用便签是一款备受青睐的电脑桌…

SecureCRT--使用sftp上传和下载文件

原文网址:SecureCRT--使用sftp上传和下载文件_IT利刃出鞘的博客-CSDN博客 简介 本文介绍SecureCRT如何在软件内直接上传和下载文件。 SecureCRT可以用如下两种方法上传和下载文件: 自带的sftp插件服务器安装rz/sz命令 本文介绍第一种方法&#xff0…

【Sping Boot2】笔记

Spring Boot 2入门 如何创建一个Spring Boot的Web例子?1.如何创建一个Spring Boot项目1.1 使用Maven构建一个Spring Boot 2项目1.1.1创建Maven工程注:Maven项目结构: 1.1.2引入SpingBoot相关依赖依赖注意事项: 1.1.3创建主类1.1.4…

CSS动画keyframes简单样例

一、代码部分 1.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><link rel"stylesheet" href…

go——Swagger使用

一. 为什么后端需要配置Swagger 在前后端分离的项目中&#xff0c;后端配置swagger可以很好的帮助前端人员了解后端接口参数和数据传输。 Swagger是一个用于设计&#xff0c;构建和文档化API的开源框架。在Go语言中&#xff0c;Swagger可以帮助后端开发人员快速创建和定义RESTf…

JVM 堆内存结构 年轻代 老年代

堆内存 内存划分 对于大多数应用&#xff0c;Java 堆是 Java 虚拟机管理的内存中最大的一块&#xff0c;被所有线程共享。此内存区域的唯一目的就是存放对象实例&#xff0c;几乎所有的对象实例以及数据都在这里分配内存。 为了进行高效的垃圾回收&#xff0c;虚拟机把堆内存…

关键路径——C语言(理论)

关键路径&#xff0c;是项目网络中从起始事件到终止事件的最长路径&#xff0c;决定了项目的最短完成时间。 关键路径中的任务没有任何可调整的余地&#xff0c;如果任何一个任务被延迟&#xff0c;整个项目的完成时间也会被延迟。 假设我们现在有一个图&#xff1a;把图的边…

高二的他已通过NOI保送北大了,让我们一起了解他的信息学奥赛学习经历吧!!!

相信关注本号的各位&#xff0c;对于信息学奥赛已经不陌生了&#xff0c;部分同学也已经开始踏入信息学的旅程&#xff0c;但前路茫茫&#xff0c;让我们一起看看已经取得成就的同学的经历吧。 今天要介绍的这位同学&#xff0c;是来自深圳中学的高二某班的欧阳达晟同学&#x…

failed to lazily initialize a collection of role,解决Hibernate查询报错

Hibernate报错&#xff1a; org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.jiuqi.gov.common.attatchment.entity.AttachmentEntity.properties, could not initialize proxy - no Session at org.hibernate.co…

docker私有仓库harbor部署

docker私有仓库harbor部署 概述 Docker 官方镜像源被中国大陆政府封锁&#xff0c;导致无法在中国大陆的计算机上直接使用 Docker 拉取镜像&#xff0c;导致使用者一下子手足无措了&#xff0c;的确一开始会有很大的影响&#xff0c;为了应对这种影响我们可以自己构建私有仓库&…

昇思25天学习打卡营第4天|yulang

今天主要了解了数据集 Dataset&#xff0c;主要包含了&#xff1a;数据集加载、数据集迭代、数据集常用操作、 可随机访问数据集、可迭代数据集、生成器。对于生成器很好理解&#xff0c;用代码来造数据&#xff0c;可以动态地生成数据。主要作用数据集通常被用于训练模型

12个视觉艺术分类

视觉设计可以按照多种方式进行分类&#xff0c;这些分类通常基于设计的目的、风格或应用场景。本文为大家介绍12种视觉设计&#xff0c;分别是平面设计、标志设计、包装设计、用户界面设计 (UI Design)、用户体验设计 (UX Design)、插图设计、网页设计、动画设计、展览设计、环…