3. 生成并存储应用密钥

生成并存储应用密钥 学习卡片

任务目标

为TC3xx平台的HSM安全启动流程生成应用密钥对(ECC-256),并使用已预置的根密钥对其公钥进行签名,生成应用密钥证书。该证书将用于后续固件签名与验签流程,确保应用密钥的合法性来源可追溯。

实现方案

本案例使用Python脚本模拟HSM内部密钥生成与签名流程,核心逻辑包括:

  • 生成应用密钥对(NIST P-256曲线)
  • 使用根私钥对应用公钥进行ECDSA签名,生成证书文件
  • 输出HSM可导入的密钥格式(十六进制)与证书文件

关键代码

import os
import hashlib
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.asymmetric.utils import encode_dss_signature

# ========== 配置 ==========
KEY_DIR = "./hsm_keys"
os.makedirs(KEY_DIR, exist_ok=True)

# 根密钥文件(预置,需提前生成)
ROOT_PRIV_PATH = os.path.join(KEY_DIR, "root_priv.pem")
ROOT_PUB_PATH = os.path.join(KEY_DIR, "root_pub.pem")

# ========== 1. 生成或加载根密钥 ==========
if not os.path.exists(ROOT_PRIV_PATH):
    root_priv = ec.generate_private_key(ec.SECP256R1())
    with open(ROOT_PRIV_PATH, "wb") as f:
        f.write(root_priv.private_bytes(
            serialization.Encoding.PEM,
            serialization.PrivateFormat.PKCS8,
            serialization.NoEncryption()))
    with open(ROOT_PUB_PATH, "wb") as f:
        f.write(root_priv.public_key().public_bytes(
            serialization.Encoding.PEM,
            serialization.PublicFormat.SubjectPublicKeyInfo))
else:
    with open(ROOT_PRIV_PATH, "rb") as f:
        root_priv = serialization.load_pem_private_key(f.read(), password=None)

# ========== 2. 生成应用密钥对 ==========
app_priv = ec.generate_private_key(ec.SECP256R1())
app_pub = app_priv.public_key()

# 保存应用私钥(HSM导入格式:原始十六进制)
app_priv_raw = app_priv.private_numbers().private_value.to_bytes(32, byteorder='big')
app_pub_raw = app_pub.public_numbers().x.to_bytes(32, byteorder='big') + \
              app_pub.public_numbers().y.to_bytes(32, byteorder='big')

with open(os.path.join(KEY_DIR, "app_priv.hex"), "w") as f:
    f.write(app_priv_raw.hex())
with open(os.path.join(KEY_DIR, "app_pub.hex"), "w") as f:
    f.write(app_pub_raw.hex())

# ========== 3. 根密钥签名应用公钥 ==========
# 对应用公钥的SHA-256哈希进行签名
pub_hash = hashlib.sha256(app_pub_raw).digest()
signature = root_priv.sign(pub_hash, ec.ECDSA(hashes.SHA256()))

# 保存证书(公钥 + 签名)
cert = {
    "app_pub_hex": app_pub_raw.hex(),
    "signature_hex": signature.hex(),
    "root_pub_hex": root_priv.public_key().public_numbers().x.to_bytes(32, byteorder='big').hex() +
                    root_priv.public_key().public_numbers().y.to_bytes(32, byteorder='big').hex()
}
with open(os.path.join(KEY_DIR, "app_cert.json"), "w") as f:
    import json
    json.dump(cert, f, indent=2)

print("应用密钥对已生成并保存至:", KEY_DIR)
print("应用公钥哈希:", pub_hash.hex()[:16], "...")
print("证书文件: app_cert.json")

运行与验证

依赖安装:

pip install cryptography

运行步骤:

python3 gen_app_key.py

验证方法:

  1. 检查hsm_keys目录下生成4个文件:root_priv.pem、root_pub.pem、app_priv.hex、app_pub.hex、app_cert.json
  2. 使用以下命令验证签名有效性:
python3 -c "
import json, hashlib
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import serialization

with open('hsm_keys/root_pub.pem','rb') as f:
    root_pub = serialization.load_pem_public_key(f.read())
with open('hsm_keys/app_cert.json') as f:
    cert = json.load(f)

app_pub_bytes = bytes.fromhex(cert['app_pub_hex'])
sig = bytes.fromhex(cert['signature_hex'])
pub_hash = hashlib.sha256(app_pub_bytes).digest()
try:
    root_pub.verify(sig, pub_hash, ec.ECDSA(hashlib.sha256))
    print('签名验证通过:应用公钥确由根密钥签名')
except Exception as e:
    print('验证失败:', e)
"

通过条件:验证脚本输出“签名验证通过”,且app_priv.hex与app_pub.hex文件内容为64位十六进制字符串(32字节密钥数据)。

HSM集成说明

在真实TC3xx平台上,上述Python脚本中的密钥生成与签名操作需替换为HSM内部API调用(如Ifx_Hsm_GenerateKey与Ifx_Hsm_Sign)。生成的app_priv.hex通过HSM安全导入接口写入非易失性存储,app_cert.json中的证书数据用于启动时的固件验签。根密钥仅在HSM内部生成且不可导出,本案例使用本地PEM文件模拟该安全边界。