首页 > 解决方案 > 如何使用 TPM 的背书密钥 (EK) 签署数据?

问题描述

我正在尝试找到一种使用 TPM 使用私有背书密钥 (EK) 对数据进行签名的方法。

使用C# 中TSS.MSR库中的示例,我能够组装一个小程序:

private void ConnectTpmAndSign()
{
   //  ************************************************************
   //  Initializes the simulated TPM.
   //  ************************************************************

    const string DefaultSimulatorName = "127.0.0.1";
    const int DefaultSimulatorPort = 2321;

    var tpmDevice = new TcpTpmDevice(DefaultSimulatorName, DefaultSimulatorPort);
    tpmDevice.Connect();

    var tpm = new Tpm2(tpmDevice);

    tpmDevice.PowerCycle();
    tpm.Startup(Su.Clear);


    //  ****************************************************
    //  Extracts the public portion of the Endorsement key.
    //  *****************************************************

    var handleEK = new TpmHandle(0x81010001);
    TpmPublic EKpub = tpm._AllowErrors().ReadPublic(handleEK, out byte[] _, out byte[] _);

    if (!tpm._LastCommandSucceeded())
        EKpub = CreateEndorsementKey(tpm, handleEK);

    //  *********************************************************
    //  Signs the data with the TPM
    //  **********************************************************
    byte[] dataToSign = new byte[] { 0x01, 0x02, 0x03 };

    // --> Fails here <--
    var signature = tpm.Sign(handleEK, dataToSign, new SigSchemeRsassa(), TpmHashCheck.Null()) as SignatureRsassa;

    ...
}

private static TpmPublic CreateEndorsementKey(Tpm2 tpm2, TpmHandle tpmHandle)
{
    TpmHandle primary = tpm2.CreatePrimary(
                new TpmHandle(TpmHandle.RhEndorsement), 
                new SensitiveCreate(/*SecretPin, null*/),
                new TpmPublic(TpmAlgId.Sha256, ObjectAttr.FixedTPM | ObjectAttr.FixedParent | ObjectAttr.SensitiveDataOrigin | ObjectAttr.AdminWithPolicy | ObjectAttr.Restricted | ObjectAttr.Decrypt, new byte[32]
                {
                    (byte) 131,
                    (byte) 113,
                    (byte) 151,
                    (byte) 103,
                    (byte) 68,
                    (byte) 132,
                    (byte) 179,
                    (byte) 248,
                    (byte) 26,
                    (byte) 144,
                    (byte) 204,
                    (byte) 141,
                    (byte) 70,
                    (byte) 165,
                    (byte) 215,
                    (byte) 36,
                    (byte) 253,
                    (byte) 82,
                    (byte) 215,
                    (byte) 110,
                    (byte) 6,
                    (byte) 82,
                    (byte) 11,
                    (byte) 100,
                    (byte) 242,
                    (byte) 161,
                    (byte) 218,
                    (byte) 27,
                    (byte) 51,
                    (byte) 20,
                    (byte) 105,
                    (byte) 170
                }, (IPublicParmsUnion)new RsaParms(new SymDefObject(TpmAlgId.Aes, (ushort)128, TpmAlgId.Cfb), (IAsymSchemeUnion)new NullAsymScheme(), (ushort)2048, 0U), (IPublicIdUnion)new Tpm2bPublicKeyRsa(new byte[256])), Array.Empty<byte>(), Array.Empty<PcrSelection>(), out TpmPublic tpmPublic, out _, out _, out _);

     tpm2.EvictControl(TpmHandle.RhOwner, primary, tpmHandle);
     tpm2.FlushContext(primary);

     return tpmPublic;
}            

该程序连接 TPM 模拟器,确保创建 EK,然后要求 TPM 使用背书密钥对数据进行签名。它失败并出现以下错误:

Tpm2Lib.TpmException: 'Error {AuthUnavailable} was returned for command Sign.     
Details:     
[Code=TpmRc.AuthUnavailable],    
[RawCode=0x12F,303]    
[ErrorEntity=Unknown],     
[ParmNum=0]     
[ParmName=Unknown]'

问题

EK 可以用来签署数据吗?如果可以,我需要做些什么才能让它发挥作用?

标签: c#tpmtss-msr

解决方案


EK 不能用于签署数据。只有 EK 几乎可以用于 AIK 注册。

不确定您的用例。但是,如果您打算使用 EK 签名作为身份证明,则可以改为使用 AIK。

  1. 生成 AIK。
  2. 现在用 AIK public 加密一些数据并要求 TPM 解密它。只有生成 AIK 的 TPM 才能解密数据。

推荐阅读