模型身份认证:验证部署模型是否被篡改
FreeGuideOnline
最新
2026-06-27
bash pip install cryptography torch
### 生成模型文件的哈希值
我们使用 SHA-256 计算模型文件的哈希。实际应用中,模型可能是 `.pt`、`.h5` 或 SavedModel 目录,对于目录可先打包为压缩文件再计算。
```python
import hashlib
def get_file_hash(filepath, algo='sha256'):
"""返回文件的哈希十六进制字符串"""
h = hashlib.new(algo)
with open(filepath, 'rb') as f:
while chunk := f.read(8192):
h.update(chunk)
return h.hexdigest()
# 示例:计算随机模型文件的哈希
import torch
import torch.nn as nn
model = nn.Linear(10, 2)
torch.save(model.state_dict(), 'model.pth')
hash_value = get_file_hash('model.pth')
print(f"模型哈希(SHA-256): {hash_value}")
记下这个哈希值,稍后用于签名。
创建数字签名(RSA示例)
下面生成一对 RSA 密钥,用私钥对哈希值进行签名,生成签名文件。实际场景中私钥必须安全离线存储。
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa, padding
def generate_keys():
"""生成RSA私钥和公钥,返回私钥路径和公钥路径"""
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
# 保存私钥(实践中需加密保护)
with open('private_key.pem', 'wb') as f:
f.write(private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.NoEncryption()
))
# 保存公钥
public_key = private_key.public_key()
with open('public_key.pem', 'wb') as f:
f.write(public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
))
return 'private_key.pem', 'public_key.pem'
def sign_hash(hash_value, private_key_path):
"""用私钥对哈希值签名"""
with open(private_key_path, 'rb') as f:
private_key = serialization.load_pem_private_key(f.read(), password=None)
signature = private_key.sign(
hash_value.encode(), # 哈希字符串转为字节
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
),
hashes.SHA256()
)
with open('model.sig', 'wb') as f:
f.write(signature)
print("签名已生成,保存至 model.sig")
private_pem, public_pem = generate_keys()
sign_hash(hash_value, private_pem)
此时目录中有了模型文件 model.pth、签名文件 model.sig 和公钥 public_key.pem。
验证签名与哈希
使用者收到模型、签名文件和公钥后,执行验证:
def verify_model(model_path, sig_path, public_key_path):
# 1. 重新计算模型哈希
new_hash = get_file_hash(model_path)
# 2. 加载公钥和签名
with open(public_key_path, 'rb') as f:
public_key = serialization.load_pem_public_key(f.read())
with open(sig_path, 'rb') as f:
signature = f.read()
# 3. 验证
try:
public_key.verify(
signature,
new_hash.encode(),
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
),
hashes.SHA256()
)
print("✅ 验证成功:模型完整且来源可信")
except Exception:
print("❌ 验证失败:模型可能被篡改或签名无效")
verify_model('model.pth', 'model.sig', public_pem)
你可以故意修改模型文件(哪怕一个权重值),再次运行验证,系统将报告验证失败。
在生产环境中实施模型身份认证
部署流程集成验证
将验证步骤硬编码进模型加载器。例如在服务启动时,自动对指定模型执行数字签名验证,失败则拒绝启动服务。伪代码:
def load_model_with_verification(model_path, sig_path, pub_key_path):
if not verify_signature(model_path, sig_path, pub_key_path):
raise SecurityException("模型身份认证失败,拒绝加载")
return load_model(model_path)
这样,任何试图加载篡改模型的请求都会被立即阻断。
自动化校验脚本
在 CI/CD 流水线中,模型构建完成后立刻自动签名,并将签名文件和公钥随模型一同打包。部署容器启动时运行校验脚本,仅当校验通过才挂载模型卷。
# Docker 入口脚本示例
#!/bin/bash
python verify.py /models/model.pth /signatures/model.sig /keys/public_key.pem
if [ $? -ne 0 ]; then
echo "Model verification failed" >&2
exit 1
fi
exec python serve.py