简体   繁体   English

C++ CNG NCrypt:无法打开来自密钥存储提供程序的持久密钥

[英]C++ CNG NCrypt: Can't open persisted key from Key Storage Provider

I have two programms.我有两个程序。 One creates a persisted key and saves it to key storage provider, then signs the hash and write the sign to the regedit.创建一个持久密钥并将其保存到密钥存储提供程序,然后签署 hash 并将签名写入 regedit。 Second program opens the key from provider and verifies the sign gotten from the regedit.第二个程序打开来自提供商的密钥并验证从注册表中获得的标志。 But my problem is in 2nd program NCryptOpenKey can't find the key in key storage provider.但我的问题是在第二个程序 NCryptOpenKey 中找不到密钥存储提供程序中的密钥。 After hours of browsing documentation and inte.net I still don't know why.在浏览文档和 inte.net 数小时后,我仍然不知道为什么。 Please point me what I am doing wrong: Code example:请指出我做错了什么:代码示例:

Variables and Cleanup procedure:变量和清理程序:

NCRYPT_PROV_HANDLE      hProv           = NULL;
NCRYPT_KEY_HANDLE       hKey            = NULL;
SECURITY_STATUS         secStatus       = ERROR_SUCCESS;
BCRYPT_ALG_HANDLE       hHashAlg        = NULL,
                        hSignAlg        = NULL;
BCRYPT_HASH_HANDLE      hHash           = NULL;
NTSTATUS                status          = STATUS_UNSUCCESSFUL;
DWORD                   cbData          = 0,
                        cbHash          = 0,
                        cbSignature     = 0,
                        cbHashObject    = 0;
PBYTE                   pbHashObject    = NULL;
PBYTE                   pbHash          = NULL,
                        pbSignature     = NULL;

static const WCHAR* KEY_NAME = TEXT("MyPersistedKey");

void Cleanup()
{
    if (hHashAlg)
        BCryptCloseAlgorithmProvider(hHashAlg, 0);

    if (hSignAlg)
        BCryptCloseAlgorithmProvider(hSignAlg, 0);

    if (hHash)
        BCryptDestroyHash(hHash);

    if (pbHashObject)
        HeapFree(GetProcessHeap(), 0, pbHashObject);

    if (pbHash)
        HeapFree(GetProcessHeap(), 0, pbHash);

    if (pbSignature)
        HeapFree(GetProcessHeap(), 0, pbSignature);

    if (hKey)
        NCryptDeleteKey(hKey, 0);

    if (hProv)
         NCryptFreeObject(hProv);
}

1st program第一个程序

// open handle to KSP
if (FAILED(secStatus = NCryptOpenStorageProvider(&hProv, MS_KEY_STORAGE_PROVIDER, 0))) {
    Cleanup();
    return {};
}
// key doesn't exists. create it
if (FAILED(secStatus = NCryptCreatePersistedKey(hProv, &hKey, NCRYPT_ECDSA_P256_ALGORITHM, KEY_NAME, 0, 0))) {
    Cleanup();
    return {};
}
// create key on disk
if (FAILED(secStatus = NCryptFinalizeKey(hKey, 0))) {
    Cleanup();
    return {};
}
// get the length of the signature
if (FAILED(secStatus = NCryptSignHash(hKey, NULL, pbHash, cbHash, NULL, 0, &cbSignature, 0))) {
    Cleanup();
    return {};
}
// allocate the signature buffer
pbSignature = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbSignature);
if (NULL == pbSignature) {
    Cleanup();
    return {};
}
// sign the hash
if (FAILED(secStatus = NCryptSignHash(hKey, NULL, pbHash, cbHash, pbSignature, cbSignature, &cbSignature, 0))) {
    Cleanup();
    return {};
}

2nd program第二期节目

// open handle to KSP
if (FAILED(secStatus = NCryptOpenStorageProvider(&hProv, MS_KEY_STORAGE_PROVIDER, 0))) {
    Cleanup();
    return false;
}
// open key from KSP
if (FAILED(secStatus = NCryptOpenKey(hProv, &hKey, KEY_NAME, 0, 0))) {
    Cleanup();
    return false;
}

// verify signature with hash
status = NCryptVerifySignature(hKey, NULL, pbHash, cbHash, pbSignature, cbSignature, 0);
switch (status) {
case ERROR_SUCCESS:   // hash is verifyied
    Cleanup();
    return true;
case NTE_BAD_SIGNATURE:   // hash isn't verifyied
    Cleanup();
    return false;
default:
    Cleanup();
    return false;
}

According to NCryptVerifySignature ,根据NCryptVerifySignature

The handle of the key must be an identical key( Symmetric keys ) or the public key portion of the key pair( Asymmetric keys ) used to sign the data with the NCryptSignHash function.密钥的句柄必须是相同的密钥( 对称密钥)或密钥对的公钥部分( 非对称密钥),用于使用 NCryptSignHash function 对数据进行签名。

And you need to export the public key.并且您需要导出公钥。 See Signing Data with CNG and SignHashWithPersistedKeys examples.请参阅使用 CNGSignHashWithPersistedKeys示例对数据进行签名。
To delete the key file on disk , pass the handle to the NCryptDeleteKey function. You have deleted the key in Cleanup .要删除磁盘上的密钥文件,请将句柄传递给NCryptDeleteKey function。您已在Cleanup中删除了密钥。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM