RE: Using Win32 CryptDecrypt to Decrypt RijndaelManaged




Thanks for the reply. As you hinted at, it was a size issue of one the
algorithm initializers. I didn't realize that the BlockSize needed to be 128
(see my reply to Dave Herrmann below) in the .NET side to match up with AES
in Crypto.

Thanks again,

Clayton

"lelteto" wrote:

1. Did you check the output sizes? While CryptEncrypt generates the plain
output, .Net may add addition info to the output block.
2. Did you check the encryption output from BOTH CAPI and .Net using the
same data, key and IV? I guess you will find the CAPI output INSIDE
(somewhere) the .NET output.
Now you "just" have to figure out - or get definitive information from
Microsoft - what other data present in the .Net output and how to interpret
that.

Laszlo Elteto
Safenet, Inc.

"Clayton Williams" wrote:

I have library that generates encrypted strings using 256-bit RijndaelManaged
in a .NET library.

I am trying to write a Win32 app that can decrypt that string using the
Crypto APIs.

I can get both to encrypt and decrypt successfully in their own projects,
but I have been unable to get the Win32 based CryptDecrypt algorithm to
successfully decrypt the RijndaelManaged encrypted string.

I am using the same Key and IV for each one, the same string, etc. As far
as I can tell, I am using the same Padding, bit size, algorithm.

This whole post boils down to 2 questions that someone may have already
resolved in a similar scenario:

1) Is it easier to write one unmanaged C++ library source that both
applications share, with a managed wrapper in the .NET assembly that all use
the Win32 Crypto library, or:
2) Is there some tweak that I am missing that will enable me to decrypt my
.NET encrypted strings in CryptDecrypt?

I have listed code from apps to illustrate where I am. The resultant byte
arrays from both encryptions are different, and plugging in the byte array
from one into the other will not decrypt - NTE_BAD_DATA

Here is my .NET code:

/////////////////////////////////////////////////
Byte[] key = { 0x74, 0x6c, 0x9b, 0xf2, 0x24, 0xce, 0xdd, 0x55, 0x23, 0xba,
0x64, 0xfb, 0xe9, 0xbe, 0x17, 0x32, 0xcf, 0xf5, 0xe3, 0xf6, 0x18, 0xc0, 0x1f,
0xd5, 0x64, 0x5d, 0x84, 0xc1, 0x1a, 0xc8, 0x71, 0x7c };

Byte[] IV = { 0x18, 0x13, 0xb1, 0xb3, 0x26, 0x2b, 0x80, 0xd1, 0xe, 0x80,
0x9f, 0x47, 0xa0, 0xd9, 0x6c, 0x1f, 0xcd, 0x42, 0x1f, 0x33, 0xa9, 0x8e, 0x2f,
0x66, 0x68, 0xcf, 0x7d, 0xd6, 0x58, 0x57, 0xf2, 0xaa };

System.Security.Cryptography.RijndaelManaged rm = new
System.Security.Cryptography.RijndaelManaged();

rm.KeySize = 256;
rm.BlockSize = 256;
rm.Padding = PaddingMode.PKCS7; // default
rm.Key = key;
rm.IV = IV;

string toEncrypt = "String To Encrypt";

byte []plainTextBytes = Encoding.UTF8.GetBytes(toEncrypt);
ICryptoTransform ict = rm.CreateEncryptor();

byte []encrBytes = ict.TransformFinalBlock(plainTextBytes, 0,
plainTextBytes.Length);

string result = Convert.ToBase64String(encrBytes);

byte []dBytes = Convert.FromBase64String(result);
ICryptoTransform ict2 = rm.CreateDecryptor();
byte[] decryptedBytes = ict2.TransformFinalBlock(encrBytes, 0,
encrBytes.Length);
string plainText = Encoding.UTF8.GetString(decryptedBytes);

///////////////////////////////////////////

Here is my C++ code:

struct CryptoBlob {
BLOBHEADER header;
DWORD cbKeySize;
BYTE rgbKeyData [32];
} keyBlob;

..... <skipping _tmain initialization>

keyBlob.header.bType = PLAINTEXTKEYBLOB;
keyBlob.header.bVersion = CUR_BLOB_VERSION;
keyBlob.header.reserved = 0;
keyBlob.header.aiKeyAlg = CALG_AES_256;
keyBlob.cbKeySize = 32; // has to be in bytes, not bits

BYTE keyData[32] = { 0x74, 0x6c, 0x9b, 0xf2, 0x24, 0xce, 0xdd, 0x55, 0x23,
0xba, 0x64, 0xfb, 0xe9, 0xbe, 0x17, 0x32, 0xcf, 0xf5, 0xe3, 0xf6, 0x18, 0xc0,
0x1f, 0xd5, 0x64, 0x5d, 0x84, 0xc1, 0x1a, 0xc8, 0x71, 0x7c };

BYTE ivData[32] = { 0x18, 0x13, 0xb1, 0xb3, 0x26, 0x2b, 0x80, 0xd1, 0xe,
0x80, 0x9f, 0x47, 0xa0, 0xd9, 0x6c, 0x1f, 0xcd, 0x42, 0x1f, 0x33, 0xa9, 0x8e,
0x2f, 0x66, 0x68, 0xcf, 0x7d, 0xd6, 0x58, 0x57, 0xf2, 0xaa };

for (int idx = 0; idx < 32; idx++)
{
keyBlob.rgbKeyData[idx] = keyData[idx];
}

HCRYPTKEY hPubKey;
HCRYPTPROV hProv;
DWORD dwBlobLen;
DWORD errVal;

if (!CryptAcquireContext(
&hProv,
NULL,
NULL,
PROV_RSA_AES,
CRYPT_VERIFYCONTEXT))
{
errVal = GetLastError();
ErrLookup(errVal);
if (NTE_BAD_KEYSET == errVal)
{
if (!CryptAcquireContext(
&hProv,
_T("NVCryptoTestContainer"),
MS_ENHANCED_PROV,
PROV_RSA_AES,
CRYPT_NEWKEYSET |

CRYPT_VERIFYCONTEXT))
{
errVal = GetLastError();
ErrLookup(errVal);
printf("Error in AcquireContext 0x%08x \n", errVal);
return 1;
}

}
}
else
{
if (CryptImportKey(hProv, (const LPBYTE)&keyBlob, sizeof(keyBlob), 0, 0,
&hPubKey))
{
if (!CryptSetKeyParam(hPubKey, KP_IV, ivData, 0))
{
ErrLookup(GetLastError());
}
else
{
char szClearText[32];
strcpy(szClearText, "String To Encrypt");

DWORD dwDataLen = (DWORD)strlen(szClearText);
DWORD dwBufferSize = sizeof(szClearText);

if(!CryptEncrypt(hPubKey, 0, TRUE, 0, (LPBYTE)szClearText,
&dwDataLen, dwBufferSize))
{
ErrLookup(GetLastError());
}
else
{
printf("encrypted looks like: %s", szClearText);
dwBufferSize = sizeof(szClearText);
if(!CryptDecrypt(hPubKey, 0, TRUE, 0, (LPBYTE)zClearText, &dwBufferSize))
{
ErrLookup(GetLastError());
}
else
{
printf("decrypted looks like: %s", szClearText);
}
}
}

if(!CryptDestroyKey(hPubKey))
{
ErrLookup(GetLastError());
}
}
else
{
ErrLookup(GetLastError());
}
}


Any help is GREATLY appreciated.
.



Relevant Pages

  • Re: Byte array to string and back - newbie question
    ... // Create a symmetric algorithm. ... This is done to make encryption more ... // Encrypt a string into a string using a password ... // Decrypt a byte array into a byte array using a key and an IV ...
    (microsoft.public.dotnet.framework.aspnet.security)
  • How do I Use DPAPI to Encrypt and Decrypt Data (C#/VB.NET)?
    ... Use DPAPI to Encrypt and Decrypt Data ... The code below demonstrates how to call Data Protection API (DPAPI) ... In addition to encryption and decryption, ... public static string Encrypt ...
    (microsoft.public.dotnet.framework.aspnet.security)
  • Re: error writing encrypted byte string to a file
    ... First of all since you aren't setting the padding mode, ... was used during the encryption processes. ... > in the string and decrypt it ... ...
    (microsoft.public.dotnet.security)
  • RE: Using Win32 CryptDecrypt to Decrypt RijndaelManaged
    ... Did you check the encryption output from BOTH CAPI and .Net using the ... I am trying to write a Win32 app that can decrypt that string using the ... I can get both to encrypt and decrypt successfully in their own projects, ... DWORD cbKeySize; ...
    (microsoft.public.platformsdk.security)
  • Using Win32 CryptDecrypt to Decrypt RijndaelManaged
    ... I have library that generates encrypted strings using 256-bit RijndaelManaged ... I am trying to write a Win32 app that can decrypt that string using the ... I can get both to encrypt and decrypt successfully in their own projects, ... DWORD cbKeySize; ...
    (microsoft.public.platformsdk.security)