TFuto Asked: 2022-07-12 23:45:05 +0800 CST2022-07-12 23:45:05 +0800 CST 2022-07-12 23:45:05 +0800 CST 列出 TPM 2.0 芯片的内容 772 我想按类型列出存储在TPM芯片上的信息,只是为了在清除旧机器的TPM芯片之前将所有相关数据迁移到新机器。我不是在寻找转储私钥等,只是一个 ID 和用途列表(例如 Bitlocker 加密密钥、虚拟智能卡等)。这在 Windows 和/或 Linux 中是否有可能? (我有 dTPM 和 fTPM 配置。) tpm ftpm 2 个回答 Voted Best Answer user1686 2022-07-13T06:34:12+08:002022-07-13T06:34:12+08:00 不可能有完整的清单,因为这些数据实际上根本没有存储在芯片上。TPM 实际上只有很少的持久存储——Windows 只在其中存储一个“存储根密钥”(也称为 SRK),其他所有内容都使用 SRK 加密并返回到操作系统进行存储。 这意味着 TPM 完全不知道哪些内容已被删除,哪些内容仍存储在某个文件中。(这也意味着 TPM 永远不会“填满”,这与智能卡不同。) 例如,BitLocker“TPM”保护器仍存储在卷标头中,仅使用附加策略的 TPM_Seal() 或 TPM2_Create() 进行加密。每次需要解封保护器时,操作系统都必须将其加载回 TPM 的 RAM,TPM 使用 SRK 对其进行解密,验证策略(如果需要比较 PCR 值),然后将清除数据返回给操作系统或拒绝。 因此,您无法列出使用特定 TPM 的所有 BitLocker 卷,因为不会在任何地方跟踪该信息。(幸运的是,Windows 仅对 OS C:\ 卷使用 TPM 保护程序,因此您可以安全地排除所有“数据”卷。) Linux 中的 LUKS 使用相同的方法,尽管直到最近才“同意”LUKS2 令牌格式——过去使用了各种手动脚本,其中一些可能已将密封数据直接存储在 TPM 的 NV 存储中。但是,随着 systemd 和 cryptsetup 现在将 TPM 支持作为标准功能,密封的密钥槽总是写回 LUKS2 磁盘头。 (下面是如何使用 TPM 2.0 密封 LUKS 密钥的示例。带有“tpm2-blob”的 JSON 片段是保存 TPM 密封数据的内容。) 类似地,保存在 TPM“中”的证书密钥对(通过“平台加密提供程序”KSP)实际上存储在~\AppData\Local\Microsoft\Crypto\PCPKSP您自己的配置文件中,用于直接通过 CAPI/CNG 创建的密钥,或者存储在 LocalService 配置文件中,用于存储在 VSC 中的密钥. (这只是私钥 - 与智能卡不同,证书本身从不首先触及 TPM。当使用 VSC 时,它们存储在 VSC 的“模拟智能卡”存储中,该存储似乎位于C:/Windows/ServiceProfiles/LocalService/AppData/Local/Microsoft/Windows/SmartCard/Tpm/,而当使用直接 CNG 时他们去任何其他证书去的地方。) 您可以使用certutil在 CAPI 中获取所有证书的列表以及它们使用的 KSP – 查找“Microsoft Platform Crypto Provider”(直接 CNG)或“Microsoft Smart Card Provider”(VSC)来识别此类证书: certutil -store -silent -user My 没有直接的 Linux 等价物,因为首先在 Linux 上没有 CAPI/CNG 等价物——程序可以使用 tpm2-pkcs11(将证书存储在 SQLite 数据库中)或使用 openssl-tpm2-engine 生成的 .pem 密钥(它们只是文件分散在哪里),甚至直接使用 tpm2-tss API。 话虽如此,TPM 2.0 确实有一些持久性存储,而且不太可能直接使用它,您可以使用 Linuxtpm2-tools来尝试列出内容: 通常有 3 个左右的密钥对的空间,可以使用tpm2_getcap handles-persistent(tpm2_readpublic -c <handle>依次应用于每个显示的句柄)列出。通常,只有基于 RSA 的“存储根密钥”(用于加密数据)和“背书密钥”(用于识别 TPM 本身)存储在那里——后者无论如何都不会通过 TPM 清除来重置。 该句柄0x81000001最常用于基于 RSA 的 SRK,0x81010001用于基于 RSA 的 EK。如果使用了旧版本的 tpm2-pkcs11 工具,有时您可能会0x81000000在 Linux 上看到。 (Systemd LUKS 支持使用基于 ECDSA 的 SRK,并且不会费心持久地存储它 - 每次只需从“存储层次结构种子”重新生成它。) 还有一些通用的“NV 存储”空间,可以使用tpm2_getcap handles-nv-index和列出tpm2_nvread。在大多数情况下,它只包含一些制造商预定义的数据,例如 EK 证书(位于 0x01C00002)。由于没有任何名称,您基本上必须猜测 - 假设有问题的 NV 索引首先是可读的。 harrymc 2022-07-12T23:59:33+08:002022-07-12T23:59:33+08:00 这是不可能的,而且实际上与 TPM 作为安全且不可侵犯的存储库的目的相违背。 Microsoft 的 可信平台模块文章 列出了用于管理 TPM 的 PowerShell 命令: Clear-Tpm :将 TPM 重置为其默认状态。 ConvertTo-TpmOwnerAuth :根据提供的字符串创建 TPM 所有者授权值。 Disable-TpmAutoProvisioning :禁用 TPM 自动配置。 Enable-TpmAutoProvisioning :启用 TPM 自动配置。 Get-Tpm :获取包含有关 TPM 信息的对象。 Get-TpmEndorsementKeyInfo :获取有关 TPM 的背书密钥和证书的信息。 Get-TpmSupportedFeature :验证 TPM 是否支持指定的功能。 Import-TpmOwnerAuth :将 TPM 所有者授权值导入注册表。 Initialize-Tpm :为 TPM 执行部分配置过程。 Set-TpmOwnerAuth :更改 TPM 所有者授权值。 Unblock-Tpm :重置 TPM 锁定。 如您所见,可以将 TPM 本身作为对象进行管理,但不能将其内容管理。
不可能有完整的清单,因为这些数据实际上根本没有存储在芯片上。TPM 实际上只有很少的持久存储——Windows 只在其中存储一个“存储根密钥”(也称为 SRK),其他所有内容都使用 SRK 加密并返回到操作系统进行存储。
这意味着 TPM 完全不知道哪些内容已被删除,哪些内容仍存储在某个文件中。(这也意味着 TPM 永远不会“填满”,这与智能卡不同。)
例如,BitLocker“TPM”保护器仍存储在卷标头中,仅使用附加策略的 TPM_Seal() 或 TPM2_Create() 进行加密。每次需要解封保护器时,操作系统都必须将其加载回 TPM 的 RAM,TPM 使用 SRK 对其进行解密,验证策略(如果需要比较 PCR 值),然后将清除数据返回给操作系统或拒绝。
因此,您无法列出使用特定 TPM 的所有 BitLocker 卷,因为不会在任何地方跟踪该信息。(幸运的是,Windows 仅对 OS C:\ 卷使用 TPM 保护程序,因此您可以安全地排除所有“数据”卷。)
Linux 中的 LUKS 使用相同的方法,尽管直到最近才“同意”LUKS2 令牌格式——过去使用了各种手动脚本,其中一些可能已将密封数据直接存储在 TPM 的 NV 存储中。但是,随着 systemd 和 cryptsetup 现在将 TPM 支持作为标准功能,密封的密钥槽总是写回 LUKS2 磁盘头。
(下面是如何使用 TPM 2.0 密封 LUKS 密钥的示例。带有“tpm2-blob”的 JSON 片段是保存 TPM 密封数据的内容。)
类似地,保存在 TPM“中”的证书密钥对(通过“平台加密提供程序”KSP)实际上存储在
~\AppData\Local\Microsoft\Crypto\PCPKSP
您自己的配置文件中,用于直接通过 CAPI/CNG 创建的密钥,或者存储在 LocalService 配置文件中,用于存储在 VSC 中的密钥.(这只是私钥 - 与智能卡不同,证书本身从不首先触及 TPM。当使用 VSC 时,它们存储在 VSC 的“模拟智能卡”存储中,该存储似乎位于
C:/Windows/ServiceProfiles/LocalService/AppData/Local/Microsoft/Windows/SmartCard/Tpm/
,而当使用直接 CNG 时他们去任何其他证书去的地方。)您可以使用
certutil
在 CAPI 中获取所有证书的列表以及它们使用的 KSP – 查找“Microsoft Platform Crypto Provider”(直接 CNG)或“Microsoft Smart Card Provider”(VSC)来识别此类证书:没有直接的 Linux 等价物,因为首先在 Linux 上没有 CAPI/CNG 等价物——程序可以使用 tpm2-pkcs11(将证书存储在 SQLite 数据库中)或使用 openssl-tpm2-engine 生成的 .pem 密钥(它们只是文件分散在哪里),甚至直接使用 tpm2-tss API。
话虽如此,TPM 2.0 确实有一些持久性存储,而且不太可能直接使用它,您可以使用 Linux
tpm2-tools
来尝试列出内容:通常有 3 个左右的密钥对的空间,可以使用
tpm2_getcap handles-persistent
(tpm2_readpublic -c <handle>
依次应用于每个显示的句柄)列出。通常,只有基于 RSA 的“存储根密钥”(用于加密数据)和“背书密钥”(用于识别 TPM 本身)存储在那里——后者无论如何都不会通过 TPM 清除来重置。该句柄
0x81000001
最常用于基于 RSA 的 SRK,0x81010001
用于基于 RSA 的 EK。如果使用了旧版本的 tpm2-pkcs11 工具,有时您可能会0x81000000
在 Linux 上看到。(Systemd LUKS 支持使用基于 ECDSA 的 SRK,并且不会费心持久地存储它 - 每次只需从“存储层次结构种子”重新生成它。)
还有一些通用的“NV 存储”空间,可以使用
tpm2_getcap handles-nv-index
和列出tpm2_nvread
。在大多数情况下,它只包含一些制造商预定义的数据,例如 EK 证书(位于 0x01C00002)。由于没有任何名称,您基本上必须猜测 - 假设有问题的 NV 索引首先是可读的。这是不可能的,而且实际上与 TPM 作为安全且不可侵犯的存储库的目的相违背。
Microsoft 的 可信平台模块文章 列出了用于管理 TPM 的 PowerShell 命令:
如您所见,可以将 TPM 本身作为对象进行管理,但不能将其内容管理。