私はMicrosoftCryptoAPIを使用するためのコードを書こうとしています。目標は非常に単純です。文字列を暗号化してから復号化します。ほぼ機能しているようですが、CryptDecryptMessageの最後の呼び出しが失敗します。
したがって、文字列を正常に暗号化することができます。次に、暗号化されたバイナリ文字列を取得して復号化しようとすると、CryptDecryptMessageへの最後の呼び出しを除いてすべてが機能します。私が使用している復号化コードは以下のとおりです。
コードが立っているとき、出力バッファーの必要なサイズを取得するためのCryptDecryptMessageの最初の呼び出しは成功しますが、常にクリアテキスト文字列サイズに6を加えたものに等しいサイズを返します。次に出力バッファーのサイズを大きくし、次の呼び出しto CryptDecryptMessageは失敗します(戻り値はゼロで、ゼロdwSizeRequired
に設定され、出力バッファーには何も入れられず、GetLastError
NTE_BAD_KEYを返します)。
一方、コメントを外す#define TESTING_INCORRECT
と、動作が少し異なります。CryptDecryptMessageへの最初の呼び出しは成功します。その戻り値はゼロですが、期待どおりのをGetLastError
返します。最も重要なのは、エンコードされた元のクリアテキスト文字列のサイズで設定されることです。次に、CryptDecryptMessageを2回割り当てて呼び出しますが、上記のように再び失敗します。ERROR_MORE_DATA
dwSizeRequired
最後に、キーストアに秘密証明書キーがあります。
ここで何が悪いのか誰かが知っていますか????? ありがとう。
void decrypt(std::string& sClearTextString , const std::vector<T_Byte>& sEncryptedBinaryString, const std::string& sKey)
{
BOOL bResult;
HCRYPTPROV hProv;
bResult = CryptAcquireContext( &hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, 0);
CHECK_CRYPT_ERR( !bResult , "Unable to find crypto context");
HCERTSTORE hStore(NULL);
const char* const pcKey = sKey.empty()? "MY" : sKey.c_str();
hStore = CertOpenSystemStore( 0, pcKey);
CHECK_CRYPT_ERR( hStore==NULL, "unable to open certificate store.");
HCERTSTORE CertStoreArray[] = {hStore};
CRYPT_DECRYPT_MESSAGE_PARA DecryptParams;
DWORD DecryptParamsSize = sizeof(DecryptParams);
memset(&DecryptParams, 0, DecryptParamsSize);
DecryptParams.cbSize = DecryptParamsSize;
DecryptParams.dwMsgAndCertEncodingType = (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING);
DecryptParams.cCertStore = sizeof(CertStoreArray)/sizeof(HCERTSTORE);
DecryptParams.rghCertStore = CertStoreArray;
const BYTE* const pbContent = &sEncryptedBinaryString[0];
DWORD dwSize = STATICCAST<DWORD>(sEncryptedBinaryString.size());
DWORD dwSizeRequired = 0;
BYTE* pbOutBuffer = NULL;
//#define TESTING_INCORRECT
#ifdef TESTING_INCORRECT
std::string sDummyBuffer(2,'\0');
pbOutBuffer = (BYTE*)(&sDummyBuffer[0]);
#endif
// Get required buffer size.
bResult = CryptDecryptMessage( &DecryptParams, pbContent, dwSize, pbOutBuffer, &dwSizeRequired, NULL);
CHECK_CRYPT_ERR( !bResult && ERROR_MORE_DATA != GetLastError() , "Unable to get buffer length");
//Allocate buffer
sClearTextString.clear();
sClearTextString.resize(dwSizeRequired+1,0);
pbOutBuffer = (BYTE*)(&sClearTextString[0]);
//Now actually decryt
bResult = CryptDecryptMessage( &DecryptParams, pbContent, dwSize, pbOutBuffer, &dwSizeRequired, NULL);
CHECK_CRYPT_ERR( !bResult , "Unable to decrypt");
CertCloseStore(hStore, CERT_CLOSE_STORE_CHECK_FLAG);
CryptReleaseContext(hProv, 0);
}