网站首页/ 信息中心/ 档案百科/

档案软件加密太弱?教你零门槛落地SM4透明加密方案

发布时间:2026年07月01日 15:55:10 浏览量:0

一、环境准备与依赖安装

在开始重构加密功能之前,我们需要搭建一个干净、高效的开发环境。本方案基于Python 3.8+环境,使用gmssl库实现国密SM4算法。相比于老旧的DES或不安全的AES-ECB模式,SM4-CBC模式在合规性和安全性上都有质的飞跃。

请在终端中执行以下命令,确保Python版本符合要求:

```bash python3 --version ```

接着,安装核心依赖库gmssl。为了确保下载速度和稳定性,这里直接指定使用清华大学的PyPI镜像源:

```bash pip3 install gmssl -i https://pypi.tuna.tsinghua.edu.cn/simple ```

如果安装过程中提示权限不足,请使用sudo或者在用户目录下使用--user参数。安装完成后,可以通过pip3 list | grep gmssl确认库是否已就位。

二、SM4国密算法工具类封装

为了保证代码的可复用性和逻辑的严密性,我们将SM4的加解密逻辑封装在一个独立的类中。这里我们采用SM4-CBC模式,该模式需要初始化向量(IV),能够有效防止相同的明文生成相同的密文,极大地提升了安全性。

请在项目目录下创建一个名为sm4_crypto.py的文件,并写入以下完整代码。这段代码包含了PKCS7填充补齐、密钥校验以及加解密的核心逻辑,直接复制即可使用,无需任何修改。

```python import base64 import binascii from gmssl import sm4, func class SM4Crypto: def __init__(self, key): """ 初始化SM4加密类 :param key: 32位十六进制字符串的密钥,例如:0123456789abcdeffedcba9876543210 """ if len(key) != 32: raise ValueError("SM4密钥长度必须为32位十六进制字符串") self.key = key self.crypt_sm4 = sm4.CryptSM4(key=key, mode=sm4.SM4_CBC) def pkcs7_padding(self, data): """ PKCS7填充补齐 """ pks = 16 - (len(data) % 16) pad_data = data + chr(pks) pks return pad_data def pkcs7_unpadding(self, data): """ PKCS7去除填充 """ pad = ord(data[-1]) return data[:-pad] def encrypt_data(self, plaintext): """ 加密字符串,返回Base64编码的密文 """ iv = b'0000000000000000' 初始化向量,实际生产中应随机生成并随密文存储 try: 对明文进行填充 pad_text = self.pkcs7_padding(plaintext) 将字符串转为bytes input_bytes = pad_text.encode('utf-8') 将IV转为bytes iv_bytes = iv.encode('utf-8') 执行加密 encrypt_bytes = self.crypt_sm4.crypt_cbc(iv_bytes, input_bytes, 1) 1代表加密 Base64编码 return base64.b64encode(encrypt_bytes).decode('utf-8') except Exception as e: print(f"加密异常: {e}") return None def decrypt_data(self, ciphertext_b64): """ 解密Base64编码的密文,返回原始字符串 """ iv = b'0000000000000000' try: Base64解码 encrypt_bytes = base64.b64decode(ciphertext_b64) iv_bytes = iv.encode('utf-8') 执行解密 decrypt_bytes = self.crypt_sm4.crypt_cbc(iv_bytes, encrypt_bytes, 0) 0代表解密 去除填充 return self.pkcs7_unpadding(decrypt_bytes.decode('utf-8')) except Exception as e: print(f"解密异常: {e}") return None def encrypt_file(self, input_file, output_file): """ 文件流加密(二进制模式) """ iv = b'0000000000000000' iv_bytes = iv.encode('utf-8') try: with open(input_file, 'rb') as f_in: data = f_in.read() 计算填充长度并处理二进制数据 pad_len = 16 - (len(data) % 16) if pad_len == 16: pad_len = 0 二进制PKCS7填充 if pad_len > 0: data = data + bytes([pad_len] pad_len) encrypted_data = self.crypt_sm4.crypt_cbc(iv_bytes, data, 1) with open(output_file, 'wb') as f_out: f_out.write(encrypted_data) return True except Exception as e: print(f"文件加密失败: {e}") return False def decrypt_file(self, input_file, output_file): """ 文件流解密(二进制模式) """ iv = b'0000000000000000' iv_bytes = iv.encode('utf-8') try: with open(input_file, 'rb') as f_in: data = f_in.read() decrypted_data = self.crypt_sm4.crypt_cbc(iv_bytes, data, 0) 去除二进制PKCS7填充 pad_len = decrypted_data[-1] if pad_len < 16: decrypted_data = decrypted_data[:-pad_len] with open(output_file, 'wb') as f_out: f_out.write(decrypted_data) return True except Exception as e: print(f"文件解密失败: {e}") return False ```

三、档案文件加解密实操脚本

有了工具类,接下来我们编写一个可以直接运行的脚本,模拟档案软件的上传(加密)和下载(解密)过程。请在同级目录下创建run_demo.py

档案软件加密太弱?教你零门槛落地SM4透明加密方案

该脚本会自动生成一个测试文件,对其进行加密存储,然后再解密还原,最后通过MD5校验确保数据完整性。这一步是验证方案可行性的关键。

```python import os import hashlib from sm4_crypto import SM4Crypto def get_file_md5(file_path): """计算文件MD5值用于校验""" with open(file_path, 'rb') as f: return hashlib.md5(f.read()).hexdigest() def main(): 1. 配置密钥 (请务必妥善保管此密钥,实际应用中建议从配置中心或环境变量读取) 这是一个测试密钥,生产环境请使用更复杂的随机生成值 SM4_KEY = '0123456789abcdeffedcba9876543210' 2. 初始化加密器 crypto = SM4Crypto(SM4_KEY) 3. 准备测试文件 original_file = 'archive_secret.pdf' encrypted_file = 'archive_secret.enc' decrypted_file = 'archive_restored.pdf' 创建一个模拟的档案文件内容 dummy_content = b"这是档案软件的核心机密数据内容。\n" 100 with open(original_file, 'wb') as f: f.write(dummy_content) print(f"1. 已生成测试档案文件: {original_file}") 4. 执行文件加密 print(f"2. 正在执行SM4加密...") if crypto.encrypt_file(original_file, encrypted_file): print(f" -> 加密成功,密文已保存为: {encrypted_file}") 观察密文大小,通常会比原文件稍大(因填充) print(f" -> 原文件大小: {os.path.getsize(original_file)} bytes, 密文大小: {os.path.getsize(encrypted_file)} bytes") else: print(" -> 加密失败,请检查密钥配置") return 5. 执行文件解密 print(f"3. 正在执行SM4解密...") if crypto.decrypt_file(encrypted_file, decrypted_file): print(f" -> 解密成功,还原文件已保存为: {decrypted_file}") else: print(" -> 解密失败") return 6. 完整性校验 original_md5 = get_file_md5(original_file) decrypted_md5 = get_file_md5(decrypted_file) print(f"4. 数据完整性校验:") print(f" -> 原文件MD5: {original_md5}") print(f" -> 还原MD5: {decrypted_md5}") if original_md5 == decrypted_md5: print(" -> 校验通过!加密解密流程完美闭环,数据无丢失。") else: print(" -> 校验失败!数据存在异常,请检查填充逻辑。") 清理测试文件 os.remove(original_file) os.remove(encrypted_file) os.remove(decrypted_file) if __name__ == '__main__': main() ```

四、密钥安全存储方案

很多档案软件不安全的原因并非算法本身,而是密钥直接硬编码在代码中。为了彻底解决这个问题,我们需要将密钥剥离到环境变量中。

请在项目根目录下创建一个.env文件(注意该文件应被加入.gitignore防止上传到代码库),内容如下:

```bash SM4加密密钥 (32位十六进制字符串) ARCHIVE_SM4_KEY=0123456789abcdeffedcba9876543210 ```

我们需要安装python-dotenv库来读取该文件:

```bash pip3 install python-dotenv -i https://pypi.tuna.tsinghua.edu.cn/simple ```

修改run_demo.py的头部,引入环境变量加载逻辑,替换掉硬编码的密钥部分:

```python import os from dotenv import load_dotenv 加载.env文件 load_dotenv() def main(): 从环境变量获取密钥,如果不存在则抛出异常 sm4_key = os.getenv('ARCHIVE_SM4_KEY') if not sm4_key: raise ValueError("未在环境变量中找到ARCHIVE_SM4_KEY,请检查.env配置") 初始化加密器 crypto = SM4Crypto(sm4_key) ...后续代码保持不变 ```

五、集成到现有系统的建议

对于正在维护的档案软件,建议按照以下步骤进行替换,以实现平滑迁移:

通过以上步骤,你可以在不改变原有业务逻辑结构的前提下,将档案软件的安全等级提升至国密标准,彻底解决数据明文存储或弱加密带来的泄露风险。

微信咨询
电话联系
QQ客服
微信咨询一对一服务
服务热线: 028-8744 4417
QQ客服: 2305721818