简体   繁体   中英

Windows CAPI CryptDecrypt error key not working

I am trying to decrypt data from openssl generated private key. I have converted the public key from PEM to DER format, but when i use CryptDecrypt it throws error key does not exist . I have previously used the same method to encrypt data and decrypt using openssl, i am also aware regarding the Endianess difference in openssl and wincrypto. Here is the code if someone can point out where i am going wrong.

#include <Windows.h>
#include <wincrypt.h>

#include <stdio.h>

#pragma comment(lib, "Crypt32.lib")


char default_pub_key[] =
"-----BEGIN PUBLIC KEY-----"
"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDVTOXB/Ti8SFvP42Z1XFB6GQ+R"
"jnqs42XiTFRXWpsSTlSPMRHi8aXpf1KYzzKHMC+4hU3rrgdbOu8bl7FekDoy38No"
"PX8ACoEmRhdn8mXs+ftmIRCuEE44mtgWUme65A1nTyT8nRmAVF6roo/rry+Xkbe9"
"iC6vRBRbVzprmCv7jwIDAQAB"
"-----END PUBLIC KEY-----";

HCRYPTPROV hProv = NULL;
HCRYPTKEY hKey = NULL;
DWORD dwKeySize = 0;

void SwapBytes(char* pv, size_t n) {
    char* p = pv;
    size_t lo, hi;
    for (lo = 0, hi = n - 1; hi > lo; lo++, hi--)
    {
        char tmp = p[lo];
        p[lo] = p[hi];
        p[hi] = tmp;
    }
}

int init_crypto()
{
    LPBYTE pbBuffer;
    DWORD dwKeyBlob, dw_pub_key_len = 0;
    unsigned int offset = 22; // 22 = 1024, 24 = 2048 and so on
    DWORD dwParamSize = sizeof(DWORD);
    CERT_PUBLIC_KEY_INFO* publicKeyInfo;

    
    CryptStringToBinaryA(default_pub_key, 0, CRYPT_STRING_ANY, NULL, &dw_pub_key_len, NULL, NULL);

    pbBuffer = (LPBYTE)GlobalAlloc(GPTR, dw_pub_key_len);
    CryptStringToBinaryA(default_pub_key, 0, CRYPT_STRING_ANY, pbBuffer, &dw_pub_key_len, NULL, NULL);

    dwKeyBlob = 0;
    CryptDecodeObjectEx(X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO, pbBuffer, dw_pub_key_len, 0, NULL, NULL, &dwKeyBlob);

    publicKeyInfo = (CERT_PUBLIC_KEY_INFO*)GlobalAlloc(GPTR, dwKeyBlob);
    CryptDecodeObjectEx(X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO, pbBuffer, dw_pub_key_len, 0, NULL, publicKeyInfo, &dwKeyBlob);
    


    CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);


    CryptImportPublicKeyInfo(hProv, X509_ASN_ENCODING, publicKeyInfo, &hKey);


    CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeySize, &dwParamSize, 0);


    char da[16];
    memset(da, 0, sizeof(da));
    wsprintfA(da, "%d", dwKeySize);
    MessageBoxA(NULL, da, NULL, MB_OK);

    dwKeySize /= 8;

    return 0;
}


int main(int argc, char** argv)
{
    
    // start rsa crypto key
    init_crypto();


    // Read encrypted data
    DWORD junk;
    HANDLE hEncFile = CreateFile(L"test_enc.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    DWORD EncFileSize = GetFileSize(hEncFile, 0);
    char* EncFileBuf = (char*)GlobalAlloc(GPTR, EncFileSize + 1);
    ReadFile(hEncFile, EncFileBuf, EncFileSize, &junk, NULL);
    CloseHandle(hEncFile);


    // convert for win32
    SwapBytes((char*)EncFileBuf, EncFileSize);

    CryptDecrypt(hKey, 0, TRUE, 0,(PBYTE)EncFileBuf, &EncFileSize);

    
    hEncFile = CreateFile(L"test_dec.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    WriteFile(hEncFile, EncFileBuf, EncFileSize, &junk, NULL);
    CloseHandle(hEncFile);
    

    GlobalFree(EncFileBuf);



    // Do proper cleanup

    return 0;
    

}

CryptDecrypt

[in] hKey

A handle to the key to use for the decryption. An application obtains this handle by using either the CryptGenKey or CryptImportKey function.

You pass a wrong hKey to CryptDecrypt. Use CryptImportKey for getting an expected hKey and pass it to CryptDecrypt.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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