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

如何在OpenSSL中使用带密码保护的TPM2句柄式密钥?

问题描述

我正在开发一个项目,使用Python的tpm2-pytss库生成受TPM保护的私钥,随后尝试通过OpenSSL生成证书。但当密钥设置了密码保护(对应TPM2B_SENSITIVE_CREATE中的userAuth)时遇到问题:OpenSSL在访问TPM句柄时似乎不支持密码输入,会静默失败或抛出模糊错误。

可行操作

通过Python和tpm2-pytss生成带有持久化句柄(0x81010000)的TPM密钥对,若不设置密码(无userAuth),可通过以下命令成功生成自签名证书:

openssl req -provider tpm2 -provider default -propquery '?provider=tpm2' \
-new -x509 -subj "/C=xx/O=xx-xx/CN=tpm_protected_ca" \
-key handle:0x81010000 -days 365 -out ca.crt

不可行操作

若生成带密码的TPM密钥,OpenSSL无法正常调用该密钥,且似乎无法通过CLI或环境变量提供密码。

密钥生成简化代码

from tpm2_pytss import *
from getpass import getpass

tpm = ESAPI()

# Prompt user for password
pwd = getpass("Enter password for TPM key:")
auth = TPM2B_AUTH(pwd.encode())

# Create sensitive struct with userAuth
in_sensitive = TPM2B_SENSITIVE_CREATE(
    TPMS_SENSITIVE_CREATE(userAuth=auth)
)

# Generate secondary key under primary
private_data, public_data, *_ = tpm.create(
    parent_handle=primary_handle,
    in_sensitive=in_sensitive,
    in_public="rsa2048",
    ...
)

secondary_handle = tpm.load(...)
tpm.evict_control(..., persistent_handle=0x81010000)

具体问题

  1. 是否可通过OpenSSL的TPM2提供者使用带密码保护(即设置了userAuth)的TPM密钥?
  2. 若不可行,是否有已知的解决方法(如补丁、配置、外部工具)?或是OpenSSL本身不支持为TPM密钥提供userAuth?

补充信息

  • TPM:嵌入式Linux(Torizon)环境下的/dev/tpm0
  • OpenSSL版本:3.x(支持TPM2提供者)
  • Python TPM库:tpm2-pytss
  • TPM栈:最新版IBM TSS
  • 可通过tpm2_sign命令正常使用带密码的密钥,但OpenSSL存在限制。

解决方案与说明

1. OpenSSL TPM2提供者支持现状

当前OpenSSL 3.x的TPM2提供者原生不支持通过CLI或环境变量为TPM密钥提供userAuth密码。原因是该提供者的密钥加载逻辑未实现接收用户输入密码并传递给TPM进行授权的流程,导致访问受密码保护的TPM密钥时直接失败。

2. 可行解决方法

方法一:使用tpm2-tss-engine中间层

tpm2-tss-engine是独立于OpenSSL原生TPM2提供者的引擎,支持为TPM密钥提供密码,操作步骤如下:

  • 安装tpm2-tss-engine包(根据Torizon环境选择对应包管理方式)
  • 将受密码保护的TPM密钥导出为引擎可识别格式:
    tpm2_createek -c 0x81010000 -G rsa -u ek.pub
    tpm2_createak -C 0x81010000 -G rsa -g sha256 -s rsassa -u ak.pub -r ak.priv -n ak.name -p your_password
    
  • 配置OpenSSL使用该引擎,生成证书时通过-passin参数传递密码:
    openssl req -engine tpm2tss -keyform engine -key ak.priv -passin pass:your_password \
    -new -x509 -subj "/C=xx/O=xx-xx/CN=tpm_protected_ca" -days 365 -out ca.crt
    

方法二:临时授权TPM密钥会话

通过tpm2-tools预先建立授权会话,让OpenSSL在会话有效期内无密码访问密钥:

  1. 建立授权会话并获取会话句柄:
    tpm2_startauthsession -S session.ctx
    tpm2_policysecret -S session.ctx -c 0x81010000 -p your_password
    
  2. 在OpenSSL命令中指定会话上下文:
    OPENSSL_TPM2_SESSION=session.ctx openssl req -provider tpm2 -provider default -propquery '?provider=tpm2' \
    -new -x509 -subj "/C=xx/O=xx-xx/CN=tpm_protected_ca" -key handle:0x81010000 -days 365 -out ca.crt
    
  3. 使用完毕后关闭会话:
    tpm2_flushcontext session.ctx
    

方法三:修改OpenSSL TPM2提供者源码(进阶)

若需要原生支持,可修改OpenSSL TPM2提供者代码,添加密码输入逻辑:

  • 定位提供者中加载TPM密钥的代码段(通常在prov_tpm2.c等文件中)
  • 添加读取命令行参数(如-passin)或环境变量的逻辑,将密码转换为TPM2B_AUTH结构传递给TPM授权调用
  • 重新编译OpenSSL并替换现有版本

3. 总结

OpenSSL原生TPM2提供者暂不支持带密码的TPM密钥,推荐使用tpm2-tss-engine或临时授权会话的方式解决需求——前者适合长期稳定使用,后者适合临时场景。

内容的提问来源于stack exchange,提问作者Autolab

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 08:19:52