CNG如何使用RSA私钥签名

时间:2020-02-26 01:49:53

标签: c++ cryptography rsa cng

1。如何使用RSA私钥签名?已解决

我遵循此sample用私钥对数据签名。我只保留哈希和符号函数,并使用ECDSA P-256私钥,例如示例。

这是我的步骤,程序运行正常:

  • BCryptOpenAlgorithmProvider()
  • 哈希一些数据
  • NCryptOpenStorageProvider()
  • NCryptCreatePersistedKey()
  • NCryptFinalizeKey()
  • NCryptSignHash()
  • NCryptSignHash()

我尝试使用RSA私钥进行签名,将NCRYPT_ECDSA_P256_ALGORITHM替换为NCRYPT_RSA_ALGORITHMNCRYPT_RSA_SIGN_ALGORITHM,但是在第二NCryptSignHash()中使用NTE_INVALID_PARAMETER失败了。

    //create a persisted key
    if (FAILED(secStatus = NCryptCreatePersistedKey(
        hProv,
        &hKey,
        NCRYPT_RSA_ALGORITHM,
        L"my RSA key",
        0,
        0)))
    {
        wprintf(L"**** Error 0x%x returned by NCryptCreatePersistedKey\n", secStatus);
        goto Cleanup;
    }

2。为什么程序在首次运行后找不到私钥?

私钥是在程序中创建的,我尝试使用X509证书签名,该证书在My证书存储区中具有私钥(ECDSA P-256)。

这是我的步骤,该程序只能在第一次运行时使用。它在CryptAcquireCertificatePrivateKey()中以NTE_BAD_KEYSET error失败了

  • BCryptOpenAlgorithmProvider()
  • 哈希一些数据
  • CertOpenStore()
  • CertFindCertificateInStore()
  • CryptAcquireCertificatePrivateKey()
  • NCryptSignHash()
  • NCryptSignHash()
   // Open the certificate store.
   if (!(hCertStore = CertOpenStore(
       CERT_STORE_PROV_SYSTEM,
       0,
       NULL,
       CERT_SYSTEM_STORE_CURRENT_USER,
       CERT_STORE_NAME)))
   {
       MyHandleError(const_cast<LPTSTR>("The MY store could not be opened."));
   }
   swprintf(wMY_SIGNER_NAME, 100, L"%hs", MY_SIGNER_NAME);
   if (pSignerCert = CertFindCertificateInStore(
       hCertStore,
       MY_ENCODING_TYPE,
       0,
       CERT_FIND_SUBJECT_STR,
       wMY_SIGNER_NAME,
       NULL))
   {
       //_tprintf(TEXT("The signer's certificate was found.\n"));
   }
   else
   {
       MyHandleError(const_cast<LPTSTR>("Signer certificate not found."));
   }

   if (CryptAcquireCertificatePrivateKey(
       pSignerCert, 
       CRYPT_ACQUIRE_PREFER_NCRYPT_KEY_FLAG, NULL, 
       &hKey,
       &dwKeySpec, 
       false))
   {
       printf("Get Priv OK\n");
   }
   else
   {
       if (GetLastError() == NTE_BAD_KEYSET)
           printf("NTE_BAD_KEYSET\n");
   }

更新:

    if (FAILED(secStatus = NCryptSignHash(
        hKey,
        0,
        pbHash,
        cbHash,
        NULL,
        0,
        &cbSignature,
        0)))
    {
        wprintf(L"**** Error 0x%x returned by NCryptSignHash1\n", secStatus);
        goto Cleanup;
    }

    //allocate the signature buffer
    pbSignature = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbSignature);
    if (NULL == pbSignature)
    {
        wprintf(L"**** memory allocation failed\n");
        goto Cleanup;
    }

    if (FAILED(secStatus = NCryptSignHash(
        hKey,
        0,
        pbHash,
        cbHash,
        pbSignature,
        cbSignature,
        &cbSignature,
        0)))
    {
        wprintf(L"**** Error 0x%x returned by NCryptSignHash2\n", secStatus);
        goto Cleanup;
    }

UPDATE2:

代码在删除NCryptDeleteKey(hKey, 0)之后起作用。我认为此API会删除我的EC密钥!但是我不知道为什么不能删除RSA密钥?

0 个答案:

没有答案