首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >CryptoNextGeneration :在TPM中存储密钥

CryptoNextGeneration :在TPM中存储密钥
EN

Stack Overflow用户
提问于 2020-04-15 09:07:17
回答 2查看 403关注 0票数 3

我目前正在开发一个小的示例程序,使用Crypto Next Generation (Windows Crypto API)来生成密钥,将其存储在我计算机上的TPM中,对一些数据进行加密,然后检索并解密数据。

我选择RSA加密是因为它是我的TPM唯一支持的算法。

我知道我可以通过以下方式作为提供商访问TPM:

代码语言:javascript
复制
// Open handle to TPM
if (FAILED(secStatus = NCryptOpenStorageProvider(
    &hProv,
    MS_PLATFORM_CRYPTO_PROVIDER,
    0)))
{
    wprintf(L"**** Error 0x%x returned by NCryptOpenStorageProvider\n", secStatus);
    goto Cleanup;
}

并且我可以生成密钥(哪些文档声明应该将其保存在我的提供程序中):

代码语言:javascript
复制
    // Create a persistent key
    if (FAILED(secStatus = NCryptCreatePersistedKey(
        hProv,
        &hKey,
        NCRYPT_RSA_ALGORITHM,
        L"RSAKey0",
        0,
        0)))
    {
        wprintf(L"**** Error 0x%x returned by NCryptCreatePersistedKey\n", secStatus);
        goto Cleanup;
    }

(然后设置length、finalize等)

我的数据似乎是通过运行以下命令来加密的:

代码语言:javascript
复制
    // Encrypt Data
    if (!NT_SUCCESS(status = NCryptEncrypt(
        hKey,                    // hKey
        InputData,               // pbInput
        InputDataSize,           // cbInput
        NULL,                    // pPaddingInfo
        encryptedBuffer,         // pbOutput
        encryptedBufferSize,     // cbOutput
        &encryptedBufferSize,    // pcbResult
        NCRYPT_PAD_PKCS1_FLAG))) // dwFlags
    {
        wprintf(L"**** Failed to encrypt data. Error 0x%x returned by NCryptEncrypt\n", status);
        goto Cleanup;
    }

这看起来工作正常,没有错误,数据看起来是加密的。(我担心我可能误解了这里使用RSA加密和生成持久密钥而不是密钥对的函数用法,但因为我不需要共享公钥,所以我假设这应该是可行的)

但是,当尝试使用以下命令检索密钥时:

代码语言:javascript
复制
    // Get key from TPM
    if (FAILED(secStatus = NCryptOpenKey(
        hProv,
        &hKey,
        L"RSAKey0",
        0,
        0)))
    {
        wprintf(L"**** Error 0x%x returned by NCryptOpenKey\n", secStatus);
        goto Cleanup;
    }

我收到一个NTE_BAD_KEYSET错误。这表明没有找到钥匙。

潜在地,我发现我可能遗漏的唯一函数是NCryptExportKey,但是如果我理解正确的话,它会将密钥导出到一个内存块,而不是TPM (应该保存在CreatePersistedKey上)。

我是否错过了确保密钥存储在我的TPM中的步骤?

另外,我使用NCryptDeleteKey来清理我的加密函数,但是文档指出这只释放了密钥句柄,而不是实际存储的密钥。如何在TPM中存储密钥后将其删除?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-04-16 08:30:03

NCryptDeleteKey确实从你的TPM中删除了密钥,并清除了句柄。

这是通过使用枚举和列出关键字的实验发现的。

票数 1
EN

Stack Overflow用户

发布于 2021-10-01 20:25:13

NCryptCreatePersistedKey之后需要调用NCryptFinalizeKey(),否则它实际上永远不会存储到TPM中。这才是真正的魔术发生的地方。例如,如果您没有提升/ admin,它将在这里失败,并显示E_ACCESS

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61226988

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档