【问题标题】:CryptImportKey return "Bad Version of provider." errorCryptImportKey 返回“提供程序的错误版本”。错误
【发布时间】:2013-09-05 05:03:46
【问题描述】:

我通过 makecert.exe 创建一个证书和私钥文件 使用以下命令

makecert.exe -n "CN=test" -pe -ss my -sr LocalMachine -sky exchange -m 96 -a sha1 -len 2048 -r test.cer -sv test.pvk

我有一个 test.pvk 文件

现在我想在我的程序中使用私钥

CryptImportKey 函数返回“提供程序的错误版本”。错误

#include "stdafx.h"
#include "windows.h"
#include "tchar.h"

#include <wincrypt.h>
#include <cryptuiapi.h>

#pragma comment (lib, "crypt32.lib")
#pragma comment (lib, "cryptui.lib")

int _tmain(int argc, _TCHAR* argv[])
{   
    HANDLE hPrivateKeyFile; 

    HCRYPTPROV hCryptProv;
    HCRYPTKEY hKey;

    BYTE* pbPublicKey ;
    BYTE* pbPrivateKey;

    DWORD dwPublicKeyLen ;
    DWORD dwPrivateKeyLen;

    WCHAR* strFileName=L"test.pvk";

    // Open private key file    
    if ((hPrivateKeyFile = CreateFile(strFileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,NULL)) == INVALID_HANDLE_VALUE)
    {         
          printf(("CreateFile error 0x%x\n")); exit(0);       
    }

    // Get file size    
    if ((dwPrivateKeyLen = GetFileSize(hPrivateKeyFile, NULL)) == INVALID_FILE_SIZE)
    {   
          printf(("GetFileSize error 0x%x\n")); exit(0);               
    }

    // Create a buffer for the private key  
    if (!(pbPrivateKey = (BYTE *)malloc(dwPrivateKeyLen)))
    {         
          printf(("malloc error 0x%x\n"));  exit(0);          
    }

    // Read private key 
    if (!ReadFile(hPrivateKeyFile, pbPrivateKey, dwPrivateKeyLen, &dwPrivateKeyLen, NULL))
    {         
          printf(("ReadFile error 0x%x\n")); exit(0);          
    }

    if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0)) 
    {          
          printf(("CryptAcquireContext error 0x%x\n")); exit(0);      
    }

    // Import private key   
    if (!CryptImportKey(hCryptProv, pbPrivateKey, dwPrivateKeyLen, 0, CRYPT_EXPORTABLE, &hKey))
    {         
          printf(("CryptImportKey error 0x%x\n"));  
          DWORD lastError=GetLastError();//Bad Version of provider.
          exit(0);              
    }


    return 0;
}

【问题讨论】:

  • 等待您尝试导入没有关联解密密钥的私有密钥文件(请记住,您的私有密钥已加密)。
  • 我在创建私钥时没有输入密码

标签: c++ rsa cryptoapi


【解决方案1】:
  • 在 CryptAcquireContext 中,将最后一个参数更改为 CRYPT_NEWKEYSET|CRYPT_VERIFYCONTEXT

  • 检查 hCryptProv 的返回值。它应该是非零的。 CryptAcquireContext 可以返回 TRUE,同时将 hCryptProv 设置为零。

【讨论】:

  • 我将参数更改为 CRYPT_NEWKEYSET|CRYPT_VERIFYCONTEXT 并且 hCryptProv 不为零,但我仍然有错误
  • 不要使用默认提供程序,而是尝试使用 wincrypt.h 中的提供程序之一(大约第 512 行)。您有很多选择。
  • 您需要先使用 CryptDecodeObjectEx 对密钥进行解码,然后再导入解码后的项目。看看idrix.fr/Root/Samples/capi_pem.cpp
猜你喜欢
  • 2020-08-28
  • 2016-12-22
  • 2018-06-04
  • 1970-01-01
  • 2016-01-24
  • 2018-08-07
  • 2014-03-08
  • 1970-01-01
  • 2019-10-15
相关资源
最近更新 更多