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

做网站需要办什么证件网站后台修改导航栏

做网站需要办什么证件,网站后台修改导航栏,wordpress主题创建后门,网站域名保护几年Python 实现高效的 SM4 大文件加密解密实战指南 引言 在数据安全领域,使用对称加密算法如SM4进行数据保护非常常见。特别是当处理大文件时,合理的内存和块大小管理以及加密解密效率变得尤为重要。本文将分享如何使用Python进行大文件的SM4加密解密操作&…

Python 实现高效的 SM4 大文件加密解密实战指南


引言

在数据安全领域,使用对称加密算法如SM4进行数据保护非常常见。特别是当处理大文件时,合理的内存和块大小管理以及加密解密效率变得尤为重要。本文将分享如何使用Python进行大文件的SM4加密解密操作,并对代码进行优化,加入异常处理和内存管理措施,确保程序在处理大文件时的稳定性。


目录

  • 背景介绍
  • SM4算法概述
  • 挑战与解决方案
  • 填充处理的重要性
  • 大文件的分块处理
  • 完整代码实现
    • 环境准备
    • AlgorithmTool 类的实现
    • SM4FileHelper 类的实现(含详细注释)
  • 代码解析与说明
    • 填充与去填充
    • 按块加密解密逻辑
    • 处理最后一个数据块
  • 最佳实践与注意事项
    • 内存优化
    • 异常处理
    • 安全性考虑
  • 总结

背景介绍

SM4 是我国国家密码管理局制定的对称加密算法,被广泛应用于数据保护领域。然而,在对大文件进行加密解密时,如果不合理管理内存和块的大小,程序可能会崩溃或变得非常缓慢。我们将通过优化代码和加入合适的异常处理机制,提升程序的鲁棒性和性能。


SM4 算法概述

SM4 是一种分组对称加密算法,其块大小和密钥长度均为128位(16字节)。它的安全性和高效性使其成为移动通信、电子政务等领域的首选算法。


挑战与解决方案

初始问题

在使用SM4进行大文件加密解密时,您可能遇到以下问题:

  1. 加密后的文件大小与原始文件大小相同:加密后的文件应该比原文件略大,这是由于填充机制导致的。
  2. 解密后的文件内容不正确,无法还原到原始文件
问题分析

通过代码分析,我们发现了以下问题:

  1. 填充处理不当:加密过程中,最后一个数据块没有正确处理填充,导致加密数据的长度与原始数据不匹配。
  2. 数据块未对齐:SM4 的块大小是16字节,但在加密和解密时使用了不同的块大小,导致数据块未正确对齐。

解决方案

通过以下改进,我们修复了这些问题:

  1. 调整数据块的大小:使用16的倍数作为块大小(例如16 * 1024字节),确保数据块与SM4的块大小对齐。
  2. 正确处理填充:仅对最后一个数据块进行填充,解密时正确去除填充。
  3. 添加异常处理:引入合理的异常处理机制,确保在文件读取、加解密过程中处理意外情况。

完整代码实现(含详细注释)

环境准备

确保安装了gmssl库:

pip install gmssl
AlgorithmTool 类的实现
from gmssl.sm4 import CryptSM4, SM4_ENCRYPT, SM4_DECRYPT# 工具类:提供SM4加解密以及填充处理
class AlgorithmTool:def __init__(self):pass# 将16进制字符串转换为字节数据@staticmethoddef hex_string_to_bytes(data):return bytes.fromhex(data.replace(" ", ""))# PKCS7填充算法,确保数据长度是16字节的整数倍def pkcs7_padding(self, data):pad_len = 16 - (len(data) % 16)  # 计算需要填充的字节数padding = bytes([pad_len] * pad_len)  # 生成填充字节return data + padding  # 将填充字节附加到数据末尾# 去除PKCS7填充,恢复原始数据def pkcs7_unpadding(self, data):pad_len = data[-1]  # 读取最后一个字节,获取填充长度return data[:-pad_len]  # 移除填充字节# 使用SM4进行ECB模式加密def encrypt_sm4(self, key, value):crypt_sm4 = CryptSM4()crypt_sm4.set_key(self.hex_string_to_bytes(key), SM4_ENCRYPT)  # 设置加密密钥return crypt_sm4.crypt_ecb(value)  # 返回加密后的字节数据# 使用SM4进行ECB模式解密def decrypt_sm4(self, key, encrypted_value):crypt_sm4 = CryptSM4()crypt_sm4.set_key(self.hex_string_to_bytes(key), SM4_DECRYPT)  # 设置解密密钥decrypted_data = crypt_sm4.crypt_ecb(encrypted_value)  # 进行解密return self.pkcs7_unpadding(decrypted_data)  # 去除填充,返回解密后的数据
SM4FileHelper 类的实现(含详细注释)
import os
import io# 文件加密辅助类:提供按块加密和解密大文件的功能
class SM4FileHelper:def __init__(self, key):self.ag_tool = AlgorithmTool()  # 使用AlgorithmTool处理加解密self.key = key  # 16进制密钥self.block_size = 16 * 1024  # 块大小为16的倍数# 加密文件,并在文件开头保存原始文件大小信息def encrypt_file(self, input_file_path, output_file_path):"""按块加密文件内容,并在文件开头存储原始文件大小"""try:# 获取输入文件的总大小file_size = os.path.getsize(input_file_path)# 打开输入和输出文件with open(input_file_path, 'rb') as f_in, open(output_file_path, 'wb') as f_out:# 写入文件大小,便于解密时恢复f_out.write(file_size.to_bytes(8, byteorder='big'))# 循环按块读取文件while True:chunk = f_in.read(self.block_size)  # 读取数据块if not chunk:break  # 如果没有数据,则结束循环if len(chunk) < self.block_size:# 如果是最后一个块,进行填充后加密padded_chunk = self.ag_tool.pkcs7_padding(chunk)encrypted_chunk = self.ag_tool.encrypt_sm4(self.key, padded_chunk)else:# 如果是完整的块,直接加密encrypted_chunk = self.ag_tool.encrypt_sm4(self.key, chunk)f_out.write(encrypted_chunk)  # 写入加密后的数据except IOError as e:print(f"文件操作错误: {e}")  # 处理文件读写错误except Exception as e:print(f"加密过程中的错误: {e}")  # 处理加密过程中的其他异常# 解密文件,并恢复原始文件内容def decrypt_file(self, input_file_path, output_file_path):"""按块解密文件内容"""try:# 打开输入和输出文件with open(input_file_path, 'rb') as f_in_raw, open(output_file_path, 'wb') as f_out:f_in = io.BufferedReader(f_in_raw)# 读取文件开头的原始文件大小original_file_size = int.from_bytes(f_in.read(8), byteorder='big')decrypted_size = 0  # 已解密的数据大小# 循环按块解密文件while True:encrypted_chunk = f_in.read(self.block_size + 16)  # 读取加密数据块if not encrypted_chunk:break  # 如果没有数据,则结束循环if f_in.peek(1) == b'':  # 判断是否为最后一个块# 最后一个块,进行解密后去填充,并调整大小decrypted_chunk = self.ag_tool.decrypt_sm4(self.key, encrypted_chunk)remaining_size = original_file_size - decrypted_size  # 计算剩余未写入的大小decrypted_chunk = decrypted_chunk[:remaining_size]  # 截断填充后的多余数据else:# 非最后一个块,直接解密decrypted_chunk = self.ag_tool.decrypt_sm4(self.key, encrypted_chunk)f_out.write(decrypted_chunk)  # 写入解密后的数据decrypted_size += len(decrypted_chunk)  # 更新已解密数据的大小except IOError as e:print(f"文件操作错误: {e}")  # 处理文件读写错误except Exception as e:print(f"解密过程中的错误: {e}")  # 处理解密过程中的其他异常# 比较两个文件的大小,用于验证解密文件与原文件是否一致def compare_file_size(self, original_file_path, decrypted_file_path):"""比较两个文件的大小"""try:# 获取原文件和解密后文件的大小original_size = os.path.getsize(original_file_path)decrypted_size = os.path.getsize(decrypted_file_path)# 输出文件大小对比结果print(f"原文件大小: {original_size} 字节")print(f"解密文件大小: {decrypted_size} 字节")# 检查文件大小是否一致if original_size == decrypted_size:print("文件大小一致。")else:print("文件大小不一致!")except IOError as e:print(f"比较文件大小时的错误: {e}")  # 处理文件操作异常
测试代码
if __name__ == '__main__':key = '5A3F323272CEA0640C711129E0B6043B'  # 您的16进制密钥sm4_helper = SM4FileHelper(key)input_file = 'testbig.jpg'  # 要加密的文件encrypted_file = 'encrypted_testbig.sm4'  # 保存加密文件decrypted_file = 'decrypted_testbig.png'  # 解密后的文件# 加密文件sm4_helper.encrypt_file(input_file, encrypted_file)print(f"文件 {input_file} 已加密保存到 {encrypted_file}")# 解密文件sm4_helper.decrypt_file(encrypted_file, decrypted_file)print(f"文件 {encrypted_file} 已解密保存到 {decrypted_file}")# 比较文件大小sm4_helper.compare_file_size(input_file, decrypted_file)

代码解析与说明

填充与去填充
  • PKCS7填充:在AlgorithmTool类中实现,用于确保数据长度是块大小的整数倍。
  • 填充过程
    • 计算填充字节数pad_len = 16 - (len(data) % 16)
    • 生成填充字节padding = bytes([pad_len] * pad_len)
    • 将填充字节附加到原数据末尾。
  • 去填充过程
    • 读取最后一个字节,获取填充长度pad_len = data[-1]
    • 移除填充字节data[:-pad_len]
按块加密解密逻辑
  • 块大小选择16 * 1024字节,满足SM4的块大小为16的倍数,同时平衡处理效率和内存占用。
  • 加密逻辑
    • 按块读取文件,检查是否是最后一个块:
      • 最后一个块进行填充后加密。
      • 非最后一个块直接加密。
    • 写入加密后的数据到输出文件。
  • 解密逻辑
    • 按块读取加密文件,检查是否是最后一个块:
      • 最后一个块解密后去除填充,并根据原始文件大小截断多余字节。
      • 非最后一个块直接解密。
处理最后一个数据块
  • 加密时的填充
    • 只有最后一个数据块需要填充,确保数据长度为16字节的倍数。
  • 解密时的去填充
    • 仅对最后一个数据块进行去填充处理,并截断多余字节,确保解密文件与原文件一致。

最佳实践与注意事项

内存优化
  • 按块处理:通过分块读取,避免内存占用过高。
  • 块大小调整:根据具体情况灵活调整block_size
异常处理
  • 文件操作异常:添加try-except块,处理文件读写错误。
  • 加解密异常:捕获加解密过程中可能的错误,如密钥错误或数据格式问题。
安全性考虑
  • 密钥管理:妥善存储和传输加密密钥,避免密钥泄露。
  • 敏感信息保护:不要在日志中记录密钥或未加密数据。

总结

通过这次实践,成功解决了SM4加密和解密过程中遇到的问题,深入理解了对称加密算法的细节。正确处理数据块的填充和按块读取处理确保了内存占用的优化和加解密结果的准确性。

http://www.yayakq.cn/news/227967/

相关文章:

  • 网站技能培训班有哪些门店管理系统免费版
  • 为什么那么多人建网站做博客做图片赚钱的网站
  • 电脑网站制作免费的行情网站
  • 网站托管公司江苏省住房与城乡建设部网站
  • 最简单的网站开发软件有哪些wordpress评论添加验证码
  • 青浦网站制作有限责任公司是什么意思
  • 永康网站设计宁波百度关键词推广
  • 网站建设价格对比单汽配网站建设成本
  • 个人求职网站源代码免费行情软件app网站大全下载有图片
  • 湛江网站建设皆选小罗23制作一个论坛网站多少钱
  • alt网站标签怎么做网站建设成本核算
  • 重庆金融网站建设拍卖网站开发
  • 唯品会网站建设的目标台州律师网站建设
  • 怎样在百度能搜到自己的网站最专业网站建设
  • 培训机构网站建设方案北京网站建设 网络推广
  • 专业网站建设 公司排名wordpress 数据 拆分
  • 网站建设sem沈阳建设工程信息网下载
  • 移动网站mip天元建设集团有限公司 安百平 电话
  • 杭州公司网站开发改则网站建设
  • 建站网站排行女程序员可以干到多少岁
  • 电子商务网站建设c谷德设计网入口
  • 线上问诊网站建设上海公布最新情况
  • 网站如何自动手机版30岁学编程太晚了
  • 延吉网站建设彩票软件项目管理的主要内容有哪些?
  • 免费学编程的网站有哪些中国500强名单
  • 专业做网站价格个人网页设计作品 html模版
  • 贵阳培训网站建设长沙做电商网站设计
  • wordpress怎么编辑网站北京故宫网站建设分析
  • 怎么做接口网站珠海哪里做网站的
  • 做电影网站 资源去哪里找一键转发到wordpress