CryptoAPI problem -> decrypt possible with wrong key?
Hi
I wrote a little program that shows my problem. What I want to do is 0)
generate a pair of RSA keys (private, public). 1) encrypt some text with the
public key and 2) decrypt it with the private key... now, that works fine.
But then I tryed something else... I tryed to use the public key for
decrypting the data (which shouldn't work, as far as I know... but currently
I'm a bit confused... anyway). So I expected an error when decrypting with
the public key... but... it worked... can someone explain me this?
thanks
MR - Rudolf Meier
Here's my code:
CWinApp theApp;
using namespace std;
#include <wincrypt.h>
#pragma comment(lib, "Crypt32.lib")
#include <conio.h>
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
// MFC initialisieren und drucken. Bei Fehlschlag Fehlermeldung aufrufen.
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: Den Fehlercode an Ihre Anforderungen anpassen.
_tprintf(_T("Schwerwiegender Fehler bei der MFC-Initialisierung\n"));
nRetCode = 1;
}
else
{
printf("[0] generate keys - [1] encrypt - [2] decrypt\n");
BOOL bResult; DWORD dwError;
BYTE* pbBuffer = new BYTE[1024];
DWORD cbBuffer = 1024;
HANDLE hFile = NULL;
HCRYPTPROV hCryptProv;
bResult = CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV,
PROV_RSA_FULL, 0); dwError = GetLastError();
if (!bResult) printf("error\n");
switch(getch())
{
case '0':
{
HCRYPTKEY hKey;
bResult = CryptGenKey(hCryptProv, CALG_RSA_KEYX, CRYPT_EXPORTABLE |
AT_KEYEXCHANGE, &hKey); dwError = GetLastError();
cbBuffer = 1024;
bResult = CryptExportKey(hKey, NULL, PRIVATEKEYBLOB, 0, pbBuffer,
&cbBuffer); dwError = GetLastError();
hFile = CreateFile("C:\\private_key.dat", GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
WriteFile(hFile, pbBuffer, cbBuffer, &cbBuffer, NULL);
CloseHandle(hFile);
cbBuffer = 1024;
bResult = CryptExportKey(hKey, NULL, PUBLICKEYBLOB, 0, pbBuffer, &cbBuffer);
dwError = GetLastError();
hFile = CreateFile("C:\\public_key.dat", GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
WriteFile(hFile, pbBuffer, cbBuffer, &cbBuffer, NULL);
CloseHandle(hFile);
bResult = CryptDestroyKey(hKey); dwError = GetLastError();
}
break;
case '1':
{
hFile = CreateFile("C:\\public_key.dat", GENERIC_READ, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
ReadFile(hFile, pbBuffer, 1024, &cbBuffer, NULL);
CloseHandle(hFile);
HCRYPTKEY hKey;
bResult = CryptImportKey(hCryptProv, pbBuffer, cbBuffer, NULL,
CRYPT_EXPORTABLE | AT_KEYEXCHANGE, &hKey); dwError = GetLastError();
strcpy((char *)pbBuffer, "testtext");
cbBuffer = strlen((char *)pbBuffer) + 1;
bResult = CryptEncrypt(hKey, NULL, TRUE, 0, pbBuffer, &cbBuffer, 1024);
hFile = CreateFile("C:\\encrypted_data.dat", GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
WriteFile(hFile, pbBuffer, cbBuffer, &cbBuffer, NULL);
CloseHandle(hFile);
bResult = CryptDestroyKey(hKey); dwError = GetLastError();
}
break;
case '2':
{
hFile = CreateFile("C:\\public_key.dat", GENERIC_READ, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
// should generate an error, because I'm loading the public_key to decrypt!!
should not work!!
ReadFile(hFile, pbBuffer, 1024, &cbBuffer, NULL);
CloseHandle(hFile);
HCRYPTKEY hKey;
bResult = CryptImportKey(hCryptProv, pbBuffer, cbBuffer, NULL,
CRYPT_EXPORTABLE | AT_KEYEXCHANGE, &hKey); dwError = GetLastError();
hFile = CreateFile("C:\\encrypted_data.dat", GENERIC_READ, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
ReadFile(hFile, pbBuffer, 1024, &cbBuffer, NULL);
CloseHandle(hFile);
bResult = CryptDecrypt(hKey, NULL, TRUE, 0, pbBuffer, &cbBuffer);
bResult = (strcmp((char *)pbBuffer, "testtext") == 0);
printf("%s", (bResult ? "ok" : "error"));
bResult = CryptDestroyKey(hKey); dwError = GetLastError();
}
break;
default:
printf("wrong selection\n"); break;
}
bResult = CryptReleaseContext(hCryptProv, 0); dwError = GetLastError();
delete[] pbBuffer;
printf("\nfinished\n");
getch();
}
return nRetCode;
}