Guest
|
Posted: Wed Feb 28, 2007 2:28 am Post subject: CryptoAPI issue |
|
|
I would like to share data between a Windows C++ app and a Delphi
app. This data needs to be encrypted with the AES cypher.
I am trying to use the MS cryptoAPI under Delphi and of course there
is no built-in support.
I downloaded the jedi package for cryptoAPI 2 and made these additions
for AES:
ALG_SID_AES_128 = 14;
CALG_AES_128 = (ALG_CLASS_DATA_ENCRYPT or ALG_TYPE_BLOCK or
ALG_SID_AES_128);
PROV_RSA_AES = 24;
(these changes were all that I needed to bring over for compilation.)
I find that the data does not encrypt to the same thing under the two
applications. I am deriving my key from a string (currently set to
'password') and found by exporting the resultant keys that they do not
match.
Any ideas on how to resolve this are appreciated. Also, if there is a
better location to ask this, please let me know.
here is the code to produce the key under C++
-------------------------------------------------------------------
....
LPTSTR lpszPassword = TEXT("password");
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
HCRYPTKEY hKey = 0;
PBYTE pbBuffer = NULL,
pbKeyBlob = NULL;
// Get the handle to the default provider.
if (!CryptAcquireContext (&hProv, NULL, NULL, PROV_RSA_AES, 0))
{
DWORD ret = GetLastError();
if (ret != NTE_BAD_KEYSET)
{
wprintf (TEXT("Error 0x%x during CryptAcquireContext!
\n"),
ret);
goto exit;
}
else
{
if (!CryptAcquireContext (&hProv, NULL, NULL, PROV_RSA_FULL,
CRYPT_NEWKEYSET))
{
wprintf (TEXT("Error 0x%x during CryptAcquireContext!
\n"),
GetLastError());
goto exit;
}
}
}
// Create a hash object.
if (!CryptCreateHash (hProv, CALG_MD5, 0, 0, &hHash))
{
wprintf (TEXT("Error %x during CryptCreateHash!\n"),
GetLastError ());
goto exit;
}
// Hash in the password data.
int len = wcslen (lpszPassword); // verifying length under
debugger
if (!CryptHashData (hHash, (PBYTE)lpszPassword,
len, 0))
{
wprintf (TEXT("Error %x during CryptHashData!\n"),
GetLastError ());
goto exit;
}
// Derive a session key from the hash object.
if (!CryptDeriveKey (hProv, CALG_AES_128, hHash, 0x00800000 |
CRYPT_EXPORTABLE , &hKey))
{
wprintf (TEXT("Error %x during CryptDeriveKey!\n"),
GetLastError ());
goto exit;
}
}
DWORD dwBlobLen;
// get the Blob size
if(!CryptExportKey(
hKey,
NULL,
PLAINTEXTKEYBLOB,
0,
NULL,
&dwBlobLen))
{
printf("Error 0x%08x computing BLOB length.\n",
GetLastError());
return 1;
}
if(pbKeyBlob = (BYTE*)malloc(dwBlobLen))
{
printf("Memory has been allocated for the BLOB. \n");
}
else
{
printf("Out of memory. \n");
return 1;
}
if(!CryptExportKey(
hKey,
NULL,
PLAINTEXTKEYBLOB,
0,
pbKeyBlob,
&dwBlobLen))
{
printf("Error 0x%08x exporting key.\n", GetLastError());
return 1;
}
DWORD count = 0;
printf("Printing Key blob for verification \n");
for(count=0; count < dwBlobLen;)
{
printf("%02x ",pbKeyBlob[count]);
count ++;
}
-------------------------------------------------------------------
and here is the equivalent (or at least it is supposed to be) under
delphi
-------------------------------------------------------------------
var
ret : DWORD;
Password : string = 'password';
len : integer;
dwBlobLen : DWORD;
pbKeyBlob :PCHAR = nil;
count : integer;
s: string;
initialization
// Get the handle to the default provider.
if not CryptAcquireContext (@hProv, nil, nil, PROV_RSA_AES, 0) then
begin
ret := GetLastError();
if (ret <> NTE_BAD_KEYSET) then
begin
ShowMessage(format('Error 0x%x during CryptAcquireContext!',
[ret]));
exit;
end else begin
if not CryptAcquireContext (@hProv, nil, nil, PROV_RSA_AES,
CRYPT_NEWKEYSET) then
begin
ShowMessage(format('Error 0x%x during CryptAcquireContext!',
[GetLastError()]));
exit;
end;
end;
end;
if not CryptCreateHash (hProv, CALG_MD5, 0, 0, @hHash) then
begin
ShowMessage(format('Error %x during CryptCreateHash!',
[GetLastError()]));
exit;
end;
// Hash in the password data.
len := length(Password);
if not CryptHashData (hHash, PBYTE(password), len, 0) then
begin
ShowMessage(format('Error %x during CryptHashData!"',
[GetLastError()]));
exit;
end;
// Derive a session key from the hash object.
if not CryptDeriveKey (hProv, CALG_AES_128, hHash, $00800000 or
CRYPT_EXPORTABLE, @hKey) then
begin
ShowMessage(format('Error %x during CryptDeriveKey!',
[GetLastError()]));
exit;
end;
// get the Blob size
if( not CryptExportKey(hKey,
0,
PLAINTEXTKEYBLOB,
0,
nil,
@dwBlobLen)) then
ShowMessage(format('Error 0x%08x computing BLOB length',
[GetLastError()]));
pbKeyBlob := allocMem(dwBlobLen);
if(not CryptExportKey(hKey,
0,
PLAINTEXTKEYBLOB,
0,
PBYTE(pbKeyBlob),
@dwBlobLen)) then
ShowMessage(format('Error 0x%08x computing BLOB length',
[GetLastError()]));
s := '';
for count := 0 to pred(dwBlobLen) do
s := s+format('%02.2x ',[BYTE(pbKeyBlob[count])]);
ShowMessage ('Key = '+s);
------------------------------------------------------------------- |
|