You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中密钥文件的MAC完整性验证疑问(密码学相关)

关于基于MAC的完整性验证及代码改进

一、什么是基于MAC的完整性验证

MAC(消息认证码)是通过密钥生成的固定长度数据,核心作用是验证数据的完整性与真实性:

  • 完整性:确保你的公钥/私钥文件没被恶意篡改、也没在存储/传输中损坏
  • 真实性:确保文件确实是你自己生成的,而非他人伪造

具体实现逻辑:

  1. 生成独立的MAC密钥(需保密,别和加密密码混用)
  2. 对加密后的私钥、公钥文件内容,用MAC密钥生成对应的MAC值
  3. 将MAC值和原文件分开保存(比如存成.mac后缀的文件)
  4. 验证时,重新计算文件内容的MAC值,和保存的MAC值对比:一致则文件完整可信,不一致则文件已被篡改或损坏

二、现有代码的问题

  1. 公钥无需加密:公钥本身是公开数据,用密码保护完全没必要,徒增复杂度
  2. 缺少MAC验证逻辑:目前只完成了密钥的加密存储,没处理完整性验证需求
  3. 加盐密码直接存文件:PKCS#8格式会自动保存盐,单独存储加盐后的密码存在安全风险

三、改进后的代码示例

from Crypto.PublicKey import RSA
from Crypto.Protocol.KDF import scrypt
from Crypto.Random import get_random_bytes
from Crypto.Hash import HMAC, SHA256
import os

def generateCAkeys():
    # 加密私钥用的密码
    password = b'super secret'
    # 生成MAC专用密钥(需单独安全存储,不能丢失)
    mac_key = get_random_bytes(32)  # SHA256对应的HMAC密钥建议32字节长度

    # 生成RSA密钥对
    key = RSA.generate(2048)

    # 导出加密后的私钥:PKCS#8自动处理盐和加密流程
    encrypted_private_key = key.export_key(
        passphrase=password,
        pkcs=8,
        protection="scryptAndAES128-CBC"
    )
    private_key_path = os.path.join("keystore", "private_key.bin")
    with open(private_key_path, "wb") as f:
        f.write(encrypted_private_key)

    # 导出公钥:直接明文保存即可
    public_key = key.publickey().export_key()
    public_key_path = os.path.join("keystore", "public_key.bin")
    with open(public_key_path, "wb") as f:
        f.write(public_key)

    # 为私钥文件生成MAC并保存
    hmac = HMAC.new(mac_key, digestmod=SHA256)
    hmac.update(encrypted_private_key)
    private_mac_path = os.path.join("keystore", "private_key.bin.mac")
    with open(private_mac_path, "wb") as f:
        f.write(hmac.digest())

    # 为公钥文件生成MAC并保存
    hmac = HMAC.new(mac_key, digestmod=SHA256)
    hmac.update(public_key)
    public_mac_path = os.path.join("keystore", "public_key.bin.mac")
    with open(public_mac_path, "wb") as f:
        f.write(hmac.digest())

    # 保存MAC密钥(注意:此密钥需单独加密存储,不能和密钥文件放在一起)
    with open("mac_key.bin", "wb") as f:
        f.write(mac_key)

    print("CA密钥对生成完成,公钥:\n", public_key.decode())
    return

def verify_key_integrity(file_path, mac_path, mac_key):
    # 读取目标文件和已保存的MAC值
    with open(file_path, "rb") as f:
        content = f.read()
    with open(mac_path, "rb") as f:
        saved_mac = f.read()

    # 重新计算文件内容的MAC值
    hmac = HMAC.new(mac_key, digestmod=SHA256)
    hmac.update(content)
    computed_mac = hmac.digest()

    # 安全对比MAC值(Python的==操作符会避免计时攻击风险)
    return computed_mac == saved_mac

# 生成CA密钥对
generateCAkeys()

# 示例:验证私钥文件完整性(取消注释即可运行)
# with open("mac_key.bin", "rb") as f:
#     mac_key = f.read()
# is_valid = verify_key_integrity("keystore/private_key.bin", "keystore/private_key.bin.mac", mac_key)
# print("私钥文件完整性验证结果:", "有效" if is_valid else "无效")

四、关键注意事项

  • MAC密钥需单独保密存储:不能和密钥文件放在同一目录,也不能与加密密码共用
  • 公钥也需要完整性验证:即使公钥公开,若被篡改会导致后续加密、签名操作全部失效
  • 验证MAC时用安全比较:直接使用==对比即可,避免手动逐字节比较带来的计时攻击隐患

内容的提问来源于stack exchange,提问作者Ahmad Uzzam Masood

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 15:20:22