#include "stdafx.h"
#include <windows.h>
#include <wincrypt.h>
#include <malloc.h>
#include <iostream.h>
// Compute cyclic redundancy checksum - from Binstock & Rex
unsigned short BinstockRexCRC(unsigned short crc, short data)
{
int i = 0;
data <<= 8;
for(i=8; i>0; i--)
{
if((data ^ crc) &0x8000)
crc = (crc << 1) ^ 0x1021;
else
crc <<= 1;
data <<= 1;
}
return(crc);
}
unsigned short ComputeCRC(long data)
{
unsigned short crc = 0;
char *d = (char*)&data;
for(int i=0; i<sizeof(long); i++)
crc = BinstockRexCRC(crc, d[i]);
return crc;
}
// Encrypt data with key
bool Encrypt(const char *data,const char *key,char *ret,long size)
{
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
HCRYPTKEY hKey = 0;
BYTE *pbData = NULL;
DWORD dwDataLen;
if (!data || !key || !ret)
return false;
// Initialize CryptoAPI
CryptAcquireContext(&hProv, NULL, MS_DEF_PROV,
PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
CryptHashData(hHash, (BYTE*)key, strlen(key), 0);
CryptDeriveKey(hProv, CALG_RC2, hHash, 0, &hKey);
// How big a buffer do I need?
dwDataLen = strlen(data)+1;
CryptEncrypt(hKey,NULL,TRUE,0,NULL,&dwDataLen,0);
// If the size is greater than half our buffer length,
// we don't have enough room
if (dwDataLen > (unsigned long) size/2)
{
if(pbData !=NULL) free(pbData);
if(hHash) CryptDestroyHash(hHash);
if(hKey) CryptDestroyKey(hKey);
if(hProv) CryptReleaseContext(hProv,0);
return false;
}
pbData = (BYTE*)malloc(dwDataLen);
strcpy ((char*)pbData,data);
DWORD inputBufferSize = dwDataLen;
dwDataLen = strlen(data)+1;
// Encrypt the data
CryptEncrypt(hKey,NULL,TRUE,0,pbData,&dwDataLen,
inputBufferSize);
// Copy the encrypted data to a hex string
char szBuf[3];
ret[0] = 0;
for (int j=0; j< (int)dwDataLen; j++)
{
sprintf (szBuf,"%02X",pbData[j]);
strcat(ret,szBuf);
}
if(pbData !=NULL) free(pbData);
if(hHash) CryptDestroyHash(hHash);
if(hKey) CryptDestroyKey(hKey);
if(hProv) CryptReleaseContext(hProv,0);
return true;
}
// Decrypt data with key
bool Decrypt(const char *data,const char *key,char *ret,long size)
{
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
HCRYPTKEY hKey = 0;
BYTE *pbData = NULL;
DWORD dwDataLen;
if (!data || !key ||!ret || strlen(data)%2)
return false;
// Convert the string from hex to bin
pbData = (BYTE*)malloc(strlen(data)/2+10);
char szBuf[3];
for (int j=0; j<(int)strlen(data); j+=2)
{
szBuf[0] = data[j];
szBuf[1] = data[j+1];
szBuf[2] = 0;
sscanf (szBuf,"%02X",pbData+j/2);
}
// Initialize the CryptoAPI
CryptAcquireContext(&hProv, NULL, MS_DEF_PROV,
PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
CryptHashData(hHash, (BYTE*)key, strlen(key), 0);
CryptDeriveKey(hProv, CALG_RC2, hHash, 0, &hKey);
dwDataLen = strlen(data)/2;
// Decrypt the data
CryptDecrypt(hKey,0,TRUE,0,pbData,&dwDataLen);
// Is the return buffer big enough?
if (dwDataLen > (unsigned long)size/2)
{
if(pbData !=NULL) free(pbData);
if(hHash) CryptDestroyHash(hHash);
if(hKey) CryptDestroyKey(hKey);
if(hProv) CryptReleaseContext(hProv,0);
return false;
}
strcpy(ret,(const char*)pbData);
if(pbData !=NULL) free(pbData);
if(hHash) CryptDestroyHash(hHash);
if(hKey) CryptDestroyKey(hKey);
if(hProv) CryptReleaseContext(hProv,0);
return true;
}