C++ windows中的rsa加密和openssl中的解密

C++ windows中的rsa加密和openssl中的解密,c++,openssl,cryptography,rsa,cryptoapi,C++,Openssl,Cryptography,Rsa,Cryptoapi,我在“OpenSSL”和“Windows CryptoAPI”之间交换公钥时遇到问题。公钥由OpenSSL以PEM格式导出,我的程序是用C++编写的。我获取公钥并通过“CryptoAPI”加载它。加载公钥后,我加密一些数据并将它们发送到另一个应用程序。另一个应用程序不能用自己的私钥解密接收到的数据。请帮我找到解决办法 ----开始公钥----- MIGFMA0GCSQGSIB3DQEBAQAA4GNADCBIQKBGQDCJXXAO6OzesJAM5VNSYTNHWUN z8dosWEETARH

我在“OpenSSL”和“Windows CryptoAPI”之间交换公钥时遇到问题。公钥由OpenSSL以PEM格式导出,我的程序是用C++编写的。我获取公钥并通过“CryptoAPI”加载它。加载公钥后,我加密一些数据并将它们发送到另一个应用程序。另一个应用程序不能用自己的私钥解密接收到的数据。请帮我找到解决办法

----开始公钥-----
MIGFMA0GCSQGSIB3DQEBAQAA4GNADCBIQKBGQDCJXXAO6OzesJAM5VNSYTNHWUN
z8dosWEETARH6NOqq+HAOMCSV+2MgT0oOYKLf/C8I37YFXNSWANE78QNWYO3JTX
UHFJGxCLCMZ7O3Lx3OwnQRXGxW6DB95EJPENPCJ2PAFU9E75ZMGLKGW9MrIaik
XKL9u2dc9fkbc7FptQIDAQAB
-----结束公钥-----
源代码:

_ServerContextHandle = NULL;
_EncryptionKeyHandle = NULL;

void Initialize(char* inPublicKeyByPemFormat)
{
    HCRYPTPROV serverContextHandle;

    bool result = CryptAcquireContextW(&serverContextHandle, nullptr, nullptr, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) == TRUE;

    if (result)
    {
        _ServerContextHandle = serverContextHandle;

        byte derPublicKey[2048];
        DWORD derPublicKeyLength = 2048;

        result = CryptStringToBinaryA(inPublicKeyByPemFormat, 0, CRYPT_STRING_BASE64HEADER, derPublicKey, &derPublicKeyLength, nullptr, nullptr) == TRUE;

        CERT_PUBLIC_KEY_INFO* publicKeyInfo = nullptr;
        DWORD publicKeyInfoLength;

        if(result)
        {
            result = CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_PUBLIC_KEY_INFO, derPublicKey, derPublicKeyLength, CRYPT_ENCODE_ALLOC_FLAG, nullptr, &publicKeyInfo, &publicKeyInfoLength) == TRUE;
        }

        HCRYPTKEY encryptionKeyHandle;

        if(result)
        {
            result = CryptImportPublicKeyInfo(_ServerContextHandle, X509_ASN_ENCODING, publicKeyInfo, &encryptionKeyHandle) == TRUE;
        }

        LocalFree(publicKeyInfo);

        if (result)
        {
            _EncryptionKeyHandle = encryptionKeyHandle;
        }
    }
}


byte* EncryptData(byte* inData, DWORD inDataLength, DWORD* outLength) const
{
    byte* result = nullptr;

    *outLength = 0;

    DWORD length = inDataLength;

    result = CloneByteArray(inData, inDataLength);

    if (!CryptEncrypt(_EncryptionKeyHandle, NULL, TRUE, 0, result, &length, length))
    {
        delet result;

        result = new byte[length];

        CopyByteArray(inData, result, inDataLength);

        *outLength = inDataLength;

        if (!CryptEncrypt(_EncryptionKeyHandle, NULL, TRUE, 0, result, outLength, length))
        {
            delete result;

            result = nullptr;

            *outLength = 0;
        }
    }
    else
    {
        *outLength = length;
    }

    return result;
}

CryptEncrypt
,出于作者当时可能理解的原因,向后写入字节。或者,更确切地说,它以字节小/小尾端顺序写入,而几乎所有其他加密库(包括Windows CNG
BCryptEncrypt
NCryptEncrypt
例程)都以字节大/大尾端顺序写入

因此,您需要将来自
CryptEncrypt
的数据反转,并将其反转到
CryptDecrypt

例如,在.NETCore中,它调用了调用
cryptEncryptEncrypt
,然后调用
Array.Reverse
,然后返回

备注部分的最后一句是

密文以小端格式返回


CryptEncrypt
,出于作者当时可能理解的原因,向后写入字节。或者,更确切地说,它以字节小/小尾端顺序写入,而几乎所有其他加密库(包括Windows CNG
BCryptEncrypt
NCryptEncrypt
例程)都以字节大/大尾端顺序写入

因此,您需要将来自
CryptEncrypt
的数据反转,并将其反转到
CryptDecrypt

例如,在.NETCore中,它调用了调用
cryptEncryptEncrypt
,然后调用
Array.Reverse
,然后返回

备注部分的最后一句是

密文以小端格式返回


如果没有必要的信息,我们将无法调试,即使我们希望调试您的代码(请调试这不是问题,这是一个帮助请求)。在其第一个if语句中的第二个函数中,您正在删除结果值,但拼写不正确。您应该在上面的代码中说明失败的位置。它是
CryptDecodeObjectEx
还是
CryptImportPubliceInfo
还是其他什么?您应该在加载公钥后验证它。这可能意味着您需要加载测试密钥对以确保正确性。OpenSSL是big-endian,CAPI是little-endian。你可能应该从一开始。如果没有必要的信息,我们无法调试,即使我们想调试您的代码(请调试这不是问题,这是请求帮助)。在其第一个if语句内的第二个函数中,您正在删除结果值,但拼写不正确。您应该在上面的代码中说明失败的位置。它是
CryptDecodeObjectEx
还是
CryptImportPubliceInfo
还是其他什么?您应该在加载公钥后验证它。这可能意味着您需要加载测试密钥对以确保正确性。OpenSSL是big-endian,CAPI是little-endian。你可能应该从一开始。谢谢你的回复,谢谢你的回复