Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Encryption 如何使用NCryptDecrypt对OpenSSL加密的数据进行解密,并使用RSA_PKCS1_OAEP_填充?_Encryption_Cryptography - Fatal编程技术网

Encryption 如何使用NCryptDecrypt对OpenSSL加密的数据进行解密,并使用RSA_PKCS1_OAEP_填充?

Encryption 如何使用NCryptDecrypt对OpenSSL加密的数据进行解密,并使用RSA_PKCS1_OAEP_填充?,encryption,cryptography,Encryption,Cryptography,我很难使用OpenSSL和RSA_PKCS1_OAEP_填充选项对加密的数据进行解密 我正在做的是: BCRYPT_ALG_HANDLE hCryptAlg = NULL; BCRYPT_OAEP_PADDING_INFO paddingInfo = { 0 }; DWORD cbDecryptedMessage; BYTE* pbDecryptedMessage = NULL; paddingInfo.pszAlgId = BCRYPT_SHA1_AL

我很难使用OpenSSL和RSA_PKCS1_OAEP_填充选项对加密的数据进行解密

我正在做的是:

    BCRYPT_ALG_HANDLE hCryptAlg = NULL;
    BCRYPT_OAEP_PADDING_INFO paddingInfo = { 0 };
    DWORD cbDecryptedMessage;
    BYTE* pbDecryptedMessage = NULL;

    paddingInfo.pszAlgId = BCRYPT_SHA1_ALGORITHM;

    // Open an algorithm handle.
    BCryptOpenAlgorithmProvider(&hCryptAlg, BCRYPT_RSA_ALGORITHM, NULL, 0);

    // Calculate the required buffer 
    NCryptDecrypt(m_hKeyContextFull, (LPBYTE)pEncrypted, encryptedLenInBytes, &paddingInfo, NULL, cbDecryptedMessage, &outputDataLen, NCRYPT_PAD_OAEP_FLAG | NCRYPT_SILENT_FLAG);

    // After required buffer is allocated...
    NCryptDecrypt(m_hKeyContextFull, (LPBYTE)pEncrypted, encryptedLenInBytes, &paddingInfo, pbDecryptedMessage, cbDecryptedMessage, &outputDataLen, NCRYPT_PAD_OAEP_FLAG | NCRYPT_SILENT_FLAG);
它失败,NTE_参数无效(0x80090027)。我试过不同的旗子,但都不管用

注意:已使用CryptAcquireCertificatePrivateKey函数调用检索m_hKeyContextFull:

 m_hSystemStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_LOCAL_MACHINE, m_storeName.c_str());

 m_pCertWithKeys = CertFindCertificateInStore(m_hSystemStore, SupportedEncodings, 0, CERT_FIND_SUBJECT_STR, m_certName.c_str(), NULL);

 // Obtain the private key from the certificate.
 DWORD m_KeyContextSpec = 0;
 HCRYPTPROV_OR_NCRYPT_KEY_HANDLE m_hKeyContextFull;
 CryptAcquireCertificatePrivateKey(m_pCertWithKeys, CRYPT_ACQUIRE_SILENT_FLAG | CRYPT_ACQUIRE_PREFER_NCRYPT_KEY_FLAG, NULL, &m_hKeyContextFull, &m_KeyContextSpec, &m_KeyContextMustBeReleased);
注意:为了可读性,所有错误检查都已从代码中删除

你知道我做错了什么吗


谢谢。

我首先要让paddingInfo有效:

BCRYPT_OAEP_PADDING_INFO paddingInfo;
paddingInfo.pszAlgId = BCRYPT_SHA1_ALGORITHM;
paddingInfo.pbLabel = NULL;
paddingInfo.cbLabel = 0;
当前标准具有空字符串标签(请参见)

此外,对于
pbDecryptedMessage

如果此参数为NULL,则此函数将计算解密数据所需的大小,并返回pcbResult参数所指向位置的大小

所以它无论如何也不会解密。您需要首先将缓冲区分配到正确的大小;Windows API的许多工作都是这样的:首先使用输出缓冲区NULL调用它,然后以某种方式返回所需的大小,在本例中是在
outputDataLen
(您应该声明!)。然后将exputfBuffer分配到该大小,并使用新缓冲区和
cbDecryptedMessage
中的正确长度再次调用该函数。使用后,当然要再次释放缓冲区。但你的评论声称这样做了

另一个可疑的事实:您使用NCryptDecrypt,因此第一个参数 是正确类型的hKey,而
m_hKeyContextFull
似乎没有该类型
CryptAcquireCertificatePrivateKey
将为您提供一个老式的密钥句柄。 不能混合使用这些不同的Windows CryptoAPI。
也许可以看看函数,来传递它。

我不熟悉
NCrypt
系列接口,但我们最近在一个库中使用
BCrypt
系列接口实现了类似的功能。这是所讨论的功能,可以在更大的上下文中看到

在我们的例子中,描述了
prvblbtyp
LEGACY\RSAPRIVATE\BLOB
prvblbbuf
prvblbblen

静态
int
非对称解密(
常数wchar\u t*常数prvblbtyp,
常量无效*常量prvblbbuf,常量大小\u t prvblblen,
常量无效*常量ctbuf,常量大小ctlen,
无效**常数ptbuf,尺寸_t*常数ptlen)
{
BCRYPT_ALG_HANDLE halg;
国际关系;
res=INT_MIN;
if(BCryptOpenAlgorithmProvider(
&halg,BCRYPT\u RSA\u算法,NULL,0)=状态(成功){
BCRYPT_KEY_HANDLE hkey;
if(BCryptImportKeyPair(
哈尔格,
NULL、prvblbtyp和hkey,
(无效*)prvblbbuf,prvblblen,
0)==状态(成功){
b crypt_OAEP_PADDING_INFO inf;
乌龙楞;
inf.pszAlgId=BCRYPT_SHA1_算法;
inf.pbLabel=NULL;
inf.cbLabel=0;
/*
*首先使用空输出缓冲区解密。
*这将返回缓冲区所需的大小。
*/
if(BCryptDecrypt)(
香港大学,
(无效*)ctbuf,ctlen,
&中导,
NULL,0,
NULL、0和len,
b crypt\u PAD\u OAEP)=状态(成功){
无效*buf;
/*
*分配所需的缓冲区
*然后再次解密
*/
res=-ENOMEM;
buf=malloc(len);
如果(buf){
res=INT_MIN;
if(BCryptDecrypt)(
香港大学,
(无效*)ctbuf,ctlen,
&中导,
NULL,0,
布夫,兰,兰,
b crypt\u PAD\u OAEP)=状态(成功){
*ptbuf=buf;
*ptlen=len;
res=0;
}否则{
免费(buf);
}
}
}
BcryptKey(hkey);
}
BCryptCloseAlgorithmProvider(halg,0);
}
返回res;
}

m_hKeyContextFull从哪里来?RSA密钥从何处加载等。?非常不完整的代码。发布一个完整的示例,而不仅仅是一个片段。
paddingInfo
无效。嗨,Henno,谢谢你的评论,我实际上不想通过发布完整的示例来增加复杂性,使用CertOpenStore从Windows key Store加载密钥,然后调用CertFindCertificateInstare。所有加密和解密的单元测试都通过了。但问题是,当我试图解密使用OpenSSL加密的数据时,指定了RSA_PKCS1_OAEP_PADDING标志。我可以用SoftHSM解密,但在MSCRYPTO中我失败了。我会更新问题。谢谢Henno,我会尝试你的建议并让你知道结果。NCryptImportKey从内存缓冲区导入时,必须先将密钥导出到缓冲区,但结果是相同的,我无法让它工作。OpenSSL与Microsoft CNG和KSP之间是否存在任何不兼容?我可以通过这种方式成功解码使用OpenSSL+OAEP加密的字符串。这是有用的信息。