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
验证方法:
- 检查
hsm_keys目录下生成4个文件:root_priv.pem、root_pub.pem、app_priv.hex、app_pub.hex、app_cert.json - 使用以下命令验证签名有效性:
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文件模拟该安全边界。