2011-11-25 82 views
0

我寫了一個簡單的程序來加載由openssl生成的公鑰,以解密由公鑰的私鑰加密的字符串。但我不知道爲什麼我不能在CryptDecrypt winapi函數出錯?

b = CryptDecrypt(hKey,NULL,FALSE,0,pbEncrypt,&cbEncrypt); 

,我得到錯誤「8009000D NTE_NO_KEY 鍵不存在。」誰可以給我解釋一下這個 ?

void DecodeString() 
{ 

    CHAR* publicKey = 
     "-----BEGIN PUBLIC KEY-----" 
     "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv+yyzdZaqcE7qOOZ8pyN" 
     "o1n3PS2U/ewT2gGSQeixP+VixQGrxnssT3zlbeUND8CVX+tZGwkcIZZD09Rkx9vh" 
     "z7vLUFD7dngupo/aL6pfehb95citD31DUswc9BTJjQySpSSG6zWDSBJMELDYaCa4" 
     "MIU7odoCg2EbQBwRWX7upWiR+shyxnPYklY8ZUpVCtIdHXmPO5eMaI1elftqNw1N" 
     "n/Id4pFFif11Lmny3s3ADfItuyMfTwU6jwgsPaoqrX5FCnurlAVl/mcfpMVpsPju" 
     "XWw2IlvZP5SkTW4G6V+Bt+xDI6SW3dvMi6gJngHLUKekbhZxcFWuv3hus8ojpo+I" 
     "mwIDAQAB" 
     "-----END PUBLIC KEY-----"; 

    BYTE* derPubKey; 
    DWORD derPubKeyLen; 
    BOOL b = CryptStringToBinaryA(publicKey, 0, CRYPT_STRING_BASE64HEADER, NULL, &derPubKeyLen, NULL, NULL); 
    DWORD error = GetLastError(); 
    _ASSERT(error == 0); 
    _ASSERT(b == TRUE); 
    derPubKey = new BYTE[derPubKeyLen]; 
    b = CryptStringToBinaryA(publicKey, 0, CRYPT_STRING_BASE64HEADER, derPubKey, &derPubKeyLen, NULL, NULL); 
    error = GetLastError(); 
    _ASSERT(error == 0); 
    _ASSERT(b == TRUE); 
    CERT_PUBLIC_KEY_INFO *publicKeyInfo; 
    DWORD publicKeyInfoLen; 
    HCRYPTPROV hProv = 0; 
    HCRYPTKEY hKey = 0; 
    b = CryptDecodeObjectEx(X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO, derPubKey, derPubKeyLen, CRYPT_ENCODE_ALLOC_FLAG, NULL, &publicKeyInfo, &publicKeyInfoLen); 
    error = GetLastError(); 
    _ASSERT(error == 0); 
    _ASSERT(b == TRUE); 
    b = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); 
    error = GetLastError(); 
    _ASSERT(error == 0); 
    _ASSERT(b == TRUE); 
    b = CryptImportPublicKeyInfo(hProv, X509_ASN_ENCODING, publicKeyInfo, &hKey); 
    error = GetLastError(); 
    _ASSERT(error == 0); 
    _ASSERT(b == TRUE); 
    //same test decrypt 
    CHAR* sameTest = "nJZ6MN6MIrpbLQiRvfLFIHHzneQBe2rucaKSykXeHgf8Zth5FNPZPdiPhWcHq0/K" 
     "KgRHv2ON+gPyFbjsdDl2cixPgNGXs1FfI/RvkH+Icn+6rYq5uPBM5oQVriyiWI9/" 
     "QiC56LP0ooouqLg9e2U5zJmC/ftCODkFyL748Fx3godXzDl1mNB7bx/Ua6Z93KeB" 
     "OgNvYZH3tcZZYlgoX4GVf4ocO0aZ8pQjEB8p9hMWfIDRCIckDAncy21tHDmWDqZ4" 
     "H7CZjbdNyaiWe5Cr6+CYs25+r3AdIlXOKWuphgbckKDHh4r7nMX0AX+iHXGjCgkM" 
     "iwi4yz7wF+Ow/CcGHkAMTQ=="; 

    BYTE* pbEncrypt = 0; 
    DWORD cbEncrypt = 0; 
    b = CryptStringToBinaryA(sameTest, 0, CRYPT_STRING_BASE64, NULL, &cbEncrypt, NULL, NULL); 
    error = GetLastError(); 
    _ASSERT(error == 0); 
    _ASSERT(b == TRUE); 
    pbEncrypt = new BYTE[cbEncrypt]; 
    printf("%s\n",(CHAR*)pbEncrypt); 
    b = CryptStringToBinaryA(sameTest, 0, CRYPT_STRING_BASE64, pbEncrypt, &cbEncrypt, NULL, NULL); 
    error = GetLastError(); 
    _ASSERT(error == 0); 
    _ASSERT(b == TRUE); 
    printf("%s\n",(CHAR*)pbEncrypt); 
    b = CryptDecrypt(hKey,NULL,FALSE,0,pbEncrypt,&cbEncrypt); 
    error = GetLastError(); 
    _ASSERT(error == 0); 
    _ASSERT(b == TRUE); 
    printf("%s\n",(CHAR*)pbEncrypt); 
} 

回答

3

您不能使用公鑰來解密使用私鑰加密的內容。公鑰僅用於加密,而私鑰只能用於解密。

Wikipedia

[...]在公開密鑰密碼術中使用的顯着的技術是 使用非對稱密鑰算法,其中使用的密鑰來加密一個 消息是不一樣的用來解密它的密鑰。每個用戶都有一對密碼密鑰 - 一個公開加密密鑰和一個私人密鑰。公開可用的加密密鑰廣泛分佈於 ,而私人解密密鑰僅爲 收件人所知。消息使用接收者的公鑰加密,並且 只能使用相應的私鑰解密。[...]