前置准备
所需工具与依赖
所有工具均为开源免费,无授权成本,直接按以下步骤获取安装:
第一步:创建可直接复用的核心加密工具类
创建文件archive_encryptor.py,复制以下完整代码即可,代码已经处理了密钥长度校验、大文件分块加密等常见问题,不需要二次修改:
```
from gmssl import sm4
import os
import hashlib
class ArchiveEncryptor:
def __init__(self, master_key: bytes, user_id: str = None):
派生用户独立密钥,避免单密钥泄露风险
if user_id:
self.key = hashlib.sha256(master_key + user_id.encode()).digest()[:16]
else:
自动处理密钥长度,SM4要求16字节密钥
if len(master_key) < 16:
self.key = master_key.ljust(16, b'0')[:16]
else:
self.key = master_key[:16]
self.iv = bytes(16)
def encrypt_file(self, input_path: str, output_path: str) -> bool:
try:
1MB分块流式加密,支持GB级大档案文件
block_size = 1024 1024
cipher = sm4.CryptSM4()
cipher.set_key(self.key, sm4.SM4_ENCRYPT)
with open(input_path, 'rb') as infile, open(output_path, 'wb') as outfile:
while True:
block = infile.read(block_size)
if not block:
break
补齐16字节倍数块,符合SM4加密要求
if len(block) % 16 != 0:
block = block.ljust(16 ((len(block) // 16) + 1), b'\0')
encrypted_block = cipher.crypt_cbc(self.iv, block)
outfile.write(encrypted_block)
return True
except Exception as e:
print(f"加密失败:{str(e)}")
return False
def decrypt_file(self, input_path: str, output_path: str) -> bool:
try:
block_size = 1024 1024
cipher = sm4.CryptSM4()
cipher.set_key(self.key, sm4.SM4_DECRYPT)
with open(input_path, 'rb') as infile, open(output_path, 'wb') as outfile:
while True:
block = infile.read(block_size)
if not block:
break
decrypted_block = cipher.crypt_cbc(self.iv, block)
outfile.write(decrypted_block.rstrip(b'\0'))
return True
except Exception as e:
print(f"解密失败:{str(e)}")
return False
```
第二步:接入现有档案管理系统归档流程
档案管理系统的标准归档流程为「用户上传文件->临时存储->永久归档」,只需要在存入永久归档库前插入加密步骤即可,以下是两种常见场景的接入代码:
场景1:Python后端档案系统接入
在永久归档接口中添加以下代码,直接调用工具类:
```
从环境变量读取主密钥,避免硬编码泄露密钥
master_key = os.getenv('ARCHIVE_MASTER_KEY').encode('utf-8')
为当前用户派生独立密钥
encryptor = ArchiveEncryptor(master_key, user_id=str(current_user.id))
定义文件路径
raw_temp_path = f"./temp_upload/{file_uuid}.{file_ext}"
encrypted_archive_path = f"./permanent_archive/{file_uuid}.enc"
执行加密
encrypt_success = encryptor.encrypt_file(raw_temp_path, encrypted_archive_path)
if not encrypt_success:
return {"code": 500, "msg": "归档加密失败,请重试"}
删除临时明文文件,仅保留加密文件
os.remove(raw_temp_path)
```

启动服务前提前导出环境变量,命令为:export ARCHIVE_MASTER_KEY="你的16位自定义主密钥"
场景2:Java/.NET后端档案系统接入
直接引入BouncyCastle开源国密库,加密解密逻辑和上述Python版本完全一致,Maven引入坐标为:
```
org.bouncycastle
bcprov-jdk15on
1.70
```
第三步:密钥安全配置实操
- 禁止将密钥与加密文件存放在同一服务器,将主密钥存放在内网独立密钥服务器,仅允许归档服务内网访问,禁止外网连接
- 必须使用用户派生密钥,上文代码已经实现,每个客户的密钥唯一,即使单个客户密钥泄露也不会影响全系统数据
- 解密必须加权限校验,仅允许档案所有人、授权管理员发起解密,解密生成的明文临时文件,使用完成后10分钟内自动删除,禁止长期存储明文
第四步:功能验证测试
按以下步骤验证,10分钟就能完成测试:
- 准备一个任意格式的测试档案文件,命名为
test_archive.pdf,放在项目目录
- 执行加密,生成加密文件
test_archive.enc
- 执行解密,生成还原文件
test_decrypt.pdf
- 校验一致性:Windows执行命令
certutil -hashfile test_archive.pdf MD5、certutil -hashfile test_decrypt.pdf MD5;Linux执行命令md5sum test_archive.pdf test_decrypt.pdf
如果两个MD5值完全一致,说明整个流程正常可用;如果不一致,检查两个问题:1. 加密解密使用的密钥是否完全一致 2. 安装gmssl库时是否下载完整,重新执行pip install gmssl即可
整个方案开发量不超过1个工作日,无任何授权成本,符合《电子档案管理办法》和等保2.0对电子档案加密存储的要求,中小档案管理软件公司可以直接落地使用。