Asymmetric Encryption of data with BCrypt.lib at c++ side and decrypting with RSACryptoServiceProvider at c# side. (Parameter is Incorrect)
I am having a windows service written in .NET (C#) and a library written in CPP. I am generating the Public/Private Key pair in .NET side with RSACryptoServiceProvider and send the Public Key information to CPP side. At c++ end, After importing the Public Key received from C#, I am Encrypting my data with BCrypt.lib library and returning it to .net service by encoding it into base64. Now at .Net side, I am decrypting the encoded data received from c++ using RSACryptoServiceProvider.
During RSA.Decrypt() method call I am getting below exception: CryptographicException: 'The parameter is incorrect'
It seems some encoding issue to me but I am no expert here.
I have tried below solutions:
- Using Convert.FromBase64String() method to convert the received base64 data into byte array.
- I have tried to reverse the byte array received from above conversion.
Below are the code snippet I am working on.
.Net Side Code:
var rsa = RSACryptoServiceProvider.Create(1024);
var publicKey = rsa.ToXmlString(false);
var encryptedData = Convert.FromBase64String(GetEncryptedDataFromCPP(publicKey));
//Array.Reverse(encryptedData);
byte[] decryptedData = rsa.Decrypt(encryptedData, RSAEncryptionPadding.Pkcs1); //CryptographyException: Invalid Parameter
var decryptedDataValue = Encoding.UTF8.GetString(decryptedData);
.C++ Side Code:
VOID GetEncryptedDataFromCPP(publicKey)
{
BYTE* pbPublicKey = NULL;
DWORD cbExp = 3;
DWORD cbModulus = 128;
DWORD cbKey = cbExp + sizeof(BCRYPT_RSAKEY_BLOB) + cbModulus;
BCRYPT_RSAKEY_BLOB* pRsaBlob;
PBYTE pbCurrent;
//**Assuming I have fetched the Modulus and Exponent from the xml string and assigned as below.**
std::string modulus = "3XCSEveWJ3Mp41g5VxcmmlCYDL5X+VUX1ULOIl8TdsEu6bbS/Ho0ofBgAwglCrbRgAjm7ZW+EivEVLZRx5FVsEYqGX12fFZSn84Ye6D2rUYqvwR0kBE8MBCdirqg3gXAlmuIgxucWcxiT9NDTaC67Awe9yyQv3fJ2uPeOEXw0LU=";
std::string exponent = "AQAB";
std::vector<BYTE> PubKeyModulus_bin = base64_decode(PubKeyModulus);
std::vector<BYTE> PubKeyExp_bin = base64_decode(PubKeyExp);
pbPublicKey = (BYTE*)CoTaskMemAlloc(cbKey);
ZeroMemory(pbPublicKey, cbKey);
pRsaBlob = (BCRYPT_RSAKEY_BLOB*)(pbPublicKey);
// Make the Public Key Blob Header
pRsaBlob->Magic = BCRYPT_RSAPUBLIC_MAGIC;
pRsaBlob->BitLength = 128*8;
pRsaBlob->cbPublicExp = 3;
pRsaBlob->cbModulus = 128;
pRsaBlob->cbPrime1 = 0;
pRsaBlob->cbPrime2 = 0;
BCRYPT_ALG_HANDLE hAlgorithm = NULL;
BCRYPT_KEY_HANDLE hKey = NULL;
NTSTATUS status;
BYTE textData[] = "test";
DWORD textDataSize = sizeof(textData);
status = BCryptOpenAlgorithmProvider(&hAlgorithm,
BCRYPT_RSA_ALGORITHM,
NULL,
0);
if (!NT_SUCCESS(status)) {
printf("Failed to get algorithm provider..status : %08x\n", status);
}
status = BCryptImportKeyPair(hAlgorithm,
NULL,
BCRYPT_RSAPUBLIC_BLOB,
&hKey,
(PUCHAR)pbPublicKey,
cbKey,//155,
BCRYPT_NO_KEY_VALIDATION);
if (!NT_SUCCESS(status)) {
printf("Failed to import Private key..status : %08x\n", status);
}
status = BCryptEncrypt(hKey,
textData,
textDataSize,
NULL,
NULL,
0,
NULL,
0,
&encryptedBufferSize,
BCRYPT_PAD_PKCS1
);
if (!NT_SUCCESS(status)) {
printf("Failed to get required size of buffer..status : %08x\n", status);
}
encryptedBuffer = (PUCHAR)HeapAlloc(GetProcessHeap(), 0, encryptedBufferSize);
if (encryptedBuffer == NULL) {
printf("failed to allocate memory for blindedFEKBuffer\n");
}
status = BCryptEncrypt(hKey,
textData,
textDataSize,
NULL,
NULL,
0,
encryptedBuffer,
encryptedBufferSize,
&encryptedBufferSize,
BCRYPT_PAD_PKCS1
);
if (!NT_SUCCESS(status)) {
printf("Failed encrypt data..status : %08x\n", status);
}
printf("Encrypted Data\n");
printMem(encryptedBuffer, encryptedBufferSize);
printf("\n\n");
std::string encryptedDataReturn = base64_encode(&encData[0], encDataSize);
}
}
ReverseMemCpy (In Case of Little Endian, I am hoping this is the correct way)
void ReverseMemCopy(BYTE* pbDest, BYTE const* pbSource, DWORD cb)
{
for (DWORD i = 0; i < cb; i++)
{
//pbDest[cb - 1 - i] = pbSource[i]; // in case of Big Endian
pbDest[i] = pbSource[i];
}
}
Required Input and Output from Code:
Input Data: test
My Public/Private Key Pair: (Generated at .Net Side)
<RSAKeyValue><Modulus>3XCSEveWJ3Mp41g5VxcmmlCYDL5X+VUX1ULOIl8TdsEu6bbS/Ho0ofBgAwglCrbRgAjm7ZW+EivEVLZRx5FVsEYqGX12fFZSn84Ye6D2rUYqvwR0kBE8MBCdirqg3gXAlmuIgxucWcxiT9NDTaC67Awe9yyQv3fJ2uPeOEXw0LU=</Modulus><Exponent>AQAB</Exponent><P>8uB+2rMMnduKEZ/j9pIkNuHPjqOaeBi0DMkfVTHlrknVdDwCreKVHEx9XIEyYQeYdpCwmj8hwHMEVmHJhVUcjw==</P><Q>6WeNjG2cOZ6y6e+A0k12Bn5UX/HNgeBjdfyy67PG9FMioJ9znAZsJmM5dWaQD9Px3OaHEp5tJhlqrUc6U25oew==</Q><DP>FMpW0Y3GJLUoSn3vW6oC45fM1p72mBU1RGrq/bX5vUOgvARvDkd5ECUUDhkZIOkviea0119UGk8+Lc7NG1a/zQ==</DP><DQ>Sda9vAhNHRlspn9jdKSWyxUaIkQ/7G+NZ50rCVAVh+PpF4F6NIj/m+FWIyLwPmGhqW2wm55ND3mI+wqGlDBgkw==</DQ><InverseQ>Pz8NIq8+1o6PXWdWJUJPyV1Wli9NdK5RlH8yc44QJYzAxcEFnI8CPHkQu0BHrN+mfOX9UN7LfHjI9wmOVStksw==</InverseQ><D>NjayPJyLEXt7fOKDn1PWqp8iqrQLO8ree+LQLtASJtfjEWsmOpP8wMzl5LggwX/CyNLlHrOzhiVa+tZsLSziykG4CzY1qwL6HS+oSoR7GbjkSZXQPbN8RM2tS8fZ0ZyRAtn7ohDRFNMZe6Y+cFQ3H2ijARpVl4VngTqyK/Syyz0=</D></RSAKeyValue>"
Encrypted Data in Base64:
kycXjy03kP+VjWP4uYFMl4/avSOhJ269BZM/AeEj0RQmSgkfA+m9woENkDVqQuxOuw8/DqpeNreA7p11QOu3i5WNJ2wC2zhCVgXi0z+tjylQidAKiwNFNlvEfAQN3h18F/gLKkuCH7W3a7tqigxZc2jCOflA4ZeGx54ZL+gVDAw=
Encrypted Data in hex/BYTE form:
93 27 17 8f 2d 37 90 ff 95 8d 63 f8 b9 81 4c 97 8f da bd 23 a1 27 6e bd 05 93 3f 01 e1 23 d1 14 26 4a 09 1f 03 e9 bd c2 81 0d 90 35 6a 42 ec 4e bb 0f 3f 0e aa 5e 36 b7 80 ee 9d 75 40 eb b7 8b 95 8d 27 6c 02 db 38 42 56 05 e2 d3 3f ad 8f 29 50 89 d0 0a 8b 03 45 36 5b c4 7c 04 0d de 1d 7c 17 f8 0b 2a 4b 82 1f b5 b7 6b bb 6a 8a 0c 59 73 68 c2 39 f9 40 e1 97 86 c7 9e 19 2f e8 15 0c 0c
Exception at .Net Side in Decrypt()
System.Security.Cryptography.CryptographicException: 'The parameter is incorrect
Comments
Post a Comment