本文介绍了RSA_public_decrypt和MS Crypto API等效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

我正在尝试开发许可证验证解决方案。许可证使用OpenSSL的 RSA_private_encrypt 函数在服务器上编码。

I'm trying to develop a license verification solution. Licenses are encoded on server using OpenSSL's RSA_private_encrypt function.

对于Mac OX XI使用 RSA_public_decrypt ,它的工作原理就像一个魅力。在Windows上我必须使用非常小的代码,所以我不能链接到OpenSSL或其他库,我必须使用MS Crypto API。

For Mac OX X I use RSA_public_decrypt and it works like a charm. On Windows I must use very tiny bit of code, so I can not link with OpenSSL or other lib AND I have to use MS Crypto API.

我花了几天试图找出什么是错的,但没有运气。我可以成功导入公钥,但在这里我的成功结束。
我知道我需要反转字节顺序与CAPI所以这可能不是问题。

I have spent several days trying to figure out what is wrong, but with no luck. I can successfully import public key, but here my success ends.I'm aware that I need to reverse byte order with CAPI so this might not be the issue.

我已经尝试了一切,包括 CryptVerifyMessageSignatureWithKey CryptDecodeObject 使用不同的参数载入Blob,但仍然没有运气。

I have tried everything, including CryptVerifyMessageSignatureWithKey and CryptDecodeObject to load the blob with different params, but still no luck.

它总是以 GetLastError()== CRYPT_E_ASN1_BADTAG 结束,我假设意味着BLOB不是ASN1格式化... Google不会告诉输出的任何东西

It always ends up with GetLastError() == CRYPT_E_ASN1_BADTAG, which I assume means that the BLOB is not ASN1 formatted... Google does not tell anything on the output format of RSA_private_encrypt... so I am completely lost here.

以下是基于OpenSSL的OS X代码:

Here is the OS X code based on OpenSSL:

void cr_license_init(const char* lic) {
    __cr_license_ = lic;
    unsigned char lic_encoded[CR_LIC_LEN];

    BIO* b64 = BIO_new(BIO_f_base64());
    BIO* licIn = BIO_new_mem_buf((void*)lic, -1);
    licIn = BIO_push(b64, licIn);

    if(BIO_read(licIn, lic_encoded, CR_LIC_LEN) == CR_LIC_LEN) {

        const unsigned char* key_data = license_pub_der;
        RSA* r = d2i_RSA_PUBKEY(NULL, &key_data, sizeof(license_pub_der));

        if(r != NULL) {
            if(__cr_license_data_ != NULL) {
                free((void*)__cr_license_data_);
            }
            __cr_license_data_ = malloc(CR_LIC_LEN);
            if(RSA_public_decrypt(CR_LIC_LEN, lic_encoded,
    (unsigned char*)__cr_license_data_, r, RSA_PKCS1_PADDING) &lt= 0) {
                free((void*)__cr_license_data_);
                __cr_license_data_ = NULL;
            }
            RSA_free(r);
        }
    }
    BIO_free_all(licIn);
}

这部分代码在Windows上运行良好,所以我假设公钥不是一个问题。

This part of code on windows works well, so I assume public key is not an issue.

__cr_license_ = lic;
unsigned char lic_encoded[CR_LIC_LEN];

DWORD dwSize;
if(CryptStringToBinaryA(__cr_license_, 0/*autocalculate*/, CRYPT_STRING_BASE64, lic_encoded, &dwSize, NULL, NULL) && dwSize == CR_LIC_LEN) {
HCRYPTPROV hProv;
if(CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
    PCERT_PUBLIC_KEY_INFO pki = NULL;
    DWORD dwKeySize;
    if(CryptDecodeObjectEx(X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO, license_pub_der, sizeof(license_pub_der), CRYPT_ENCODE_ALLOC_FLAG, NULL, &pki, &dwKeySize)) {
        HCRYPTKEY hKey = 0;
        if(CryptImportPublicKeyInfo( hProv, X509_ASN_ENCODING, pki, &hKey)) {

之后,我尝试用消息做的事情导致 CRYPT_E_ASN1_BADTAG 。我尝试了 CryptMsgOpenToDecode CryptMsgUpdate CryptDecodeObject CryptVerifyMessageSignatureWithKey - 没有效果。

But after that anything I try to do with message leads to CRYPT_E_ASN1_BADTAG. I tried CryptMsgOpenToDecode with CryptMsgUpdate, CryptDecodeObject, CryptVerifyMessageSignatureWithKey - nothing works.

基本上我认为问题是在pkcs1和pkcs7不兼容owlstead提到。任何人都有使用pkcs1格式导入/转换/ etc与MS CAPI的经验吗?

Basically I think that the problem is in pkcs1 and pkcs7 incompatibility as owlstead mentioned. Does anyone has experience working with pkcs1 format importing/converting/etc with MS CAPI?

任何帮助,甚至线索都很感激!提前感谢!

Any help or even a clue is appreciated a lot! Thanks in advance!

推荐答案

您正在混合较高级别和较低级别的签名格式。 OpenSSL默认包含PKCS#1 v1.5签名,它仅包含签名数据。 Windows似乎似乎PKCS#7容器。这些可能包含PKCS#1 v1.5,但这些和其他数据使用ASN.1 BER标记/长度格式包装。如果Microsoft API尝试对其进行解码,则将假定原始签名是容器格式,并且解码将失败。

You are mixing higher and lower level signature formats. OpenSSL asumes PKCS#1 v1.5 signatures by default, which contains of only the signature data. Windows seems to asume PKCS#7 containers. These may contain a PKCS#1 v1.5, but those and other data are wrapped using ASN.1 BER tag/length format. If the Microsoft API tries to decode this it will assume that the raw signature is the container format, and decoding will fail.

这篇关于RSA_public_decrypt和MS Crypto API等效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 17:29