Public 使用 TSS.NET 在 TPM2 上进行密钥加密

Public key encryption on TPM2 using TSS.NET

是否可以使用 TPM2 和 Microsoft TSS.NET library 在 .Net 应用程序中实施 public 密钥加密? 更具体地说,应该在 TPM 中完成的部分是使用私钥解密,因此 public 密钥应该能够导出到其他机器。 此外,密钥应存储在 TPM2 模块中。

我 studied/worked 通过 Microsoft 的示例并阅读了 documentation,但我没有找到关于该主题的信息,或者我不知何故错过了它。

为了在TPM2中存储数据,我找到了nv内存,但据我了解,这是用来存储来自TPM2模块外部的数据的,但我不知道if/how可以将 TPM2 模块内部的某种密钥存储在其 nv 内存中,以便在下次启动时再次使用。

似乎不​​存在 C# 的示例代码(目前),但是 some sample C++ code 可以演示您想要的内容:

void Samples::RsaEncryptDecrypt()
{
    Announce("RsaEncryptDecrypt");

    // This sample demostrates the use of the TPM for RSA operations.

    // We will make a key in the "null hierarchy".
    TPMT_PUBLIC primTempl(TPM_ALG_ID::SHA1,
                          TPMA_OBJECT::decrypt | TPMA_OBJECT::userWithAuth | TPMA_OBJECT::sensitiveDataOrigin,
                          null,  // No policy
                          TPMS_RSA_PARMS(null, TPMS_SCHEME_OAEP(TPM_ALG_ID::SHA1), 2048, 65537),
                          TPM2B_PUBLIC_KEY_RSA());

    // Create the key
    auto storagePrimary = tpm.CreatePrimary(TPM_RH_NULL, null, primTempl, null, null);

    TPM_HANDLE& keyHandle = storagePrimary.handle;

    ByteVec dataToEncrypt = TPM_HASH::FromHashOfString(TPM_ALG_ID::SHA1, "secret");
    cout << "Data to encrypt: " << dataToEncrypt << endl;

    auto enc = tpm.RSA_Encrypt(keyHandle, dataToEncrypt, TPMS_NULL_ASYM_SCHEME(), null);
    cout << "RSA-encrypted data: " << enc << endl;

    auto dec = tpm.RSA_Decrypt(keyHandle, enc, TPMS_NULL_ASYM_SCHEME(), null);
    cout << "decrypted data: " << dec << endl;
    if (dec == dataToEncrypt)
        cout << "Decryption worked" << endl;
    _ASSERT(dataToEncrypt == dec);

    // Now encrypt using TSS.C++ library functions
    ByteVec mySecret = tpm._GetRandLocal(20);
    enc = storagePrimary.outPublic.Encrypt(mySecret, null);
    dec = tpm.RSA_Decrypt(keyHandle, enc, TPMS_NULL_ASYM_SCHEME(), null);
    cout << "My           secret: " << mySecret << endl;
    cout << "My decrypted secret: " << dec << endl;
    _ASSERT(mySecret == dec);

    // Now with padding
    ByteVec pad { 1, 2, 3, 4, 5, 6, 0 };
    enc = storagePrimary.outPublic.Encrypt(mySecret, pad);
    dec = tpm.RSA_Decrypt(keyHandle, enc, TPMS_NULL_ASYM_SCHEME(), pad);
    cout << "My           secret: " << mySecret << endl;
    cout << "My decrypted secret: " << dec << endl;
    _ASSERT(mySecret == dec);

    tpm.FlushContext(keyHandle);
} // RsaEncryptDecrypt()

当然,您可能不想创建新的主键,而是使用 SRK 或子键。