#include "stdafx.h"
#include <windows.h>
#include <Wincrypt.h>
#include <assert.h>
#pragma comment(lib, "crypt32.lib")
LPTSTR Base64Decode(LPCTSTR lpData, DWORD dwSize)
{
DWORD dwResult = 0;
if(CryptStringToBinary(lpData, dwSize, CRYPT_STRING_BASE64, NULL, &dwResult,NULL,NULL))
{
LPTSTR lpszBase64Decoded = new TCHAR[dwResult+(sizeof(TCHAR) * 2)];
memset(lpszBase64Decoded,0,dwResult);
if(CryptStringToBinary(lpData, dwSize, CRYPT_STRING_BASE64,(BYTE *)lpszBase64Decoded, &dwResult,NULL,NULL))
{
*(LPWORD)(lpszBase64Decoded + (dwResult / sizeof(TCHAR))) = 0;
return lpszBase64Decoded;
}
}
return NULL;
}
LPTSTR Base64Encode(LPCBYTE lpData, DWORD dwSize, BOOL bStripCRLF)
{
DWORD dwResult = 0;
if(CryptBinaryToString(lpData, dwSize, CRYPT_STRING_BASE64, NULL, &dwResult))
{
LPTSTR lpszBase64 = new TCHAR[dwResult];
if(CryptBinaryToString(lpData, dwSize, CRYPT_STRING_BASE64, lpszBase64, &dwResult))
{
TCHAR pByteLF = *(LPWORD)(lpszBase64 + dwResult -1);
TCHAR pByteCR = *(LPWORD)(lpszBase64 + dwResult -2);
if(pByteCR == 0x0D && pByteLF == 0x0A)
{
*(LPWORD)(lpszBase64 + dwResult -2) = 0;
}
return lpszBase64;
}
}
return NULL;
}
DWORD TripleDESencrypt(TCHAR *plaintext,DWORD ptlen,TCHAR *passwd,DWORD pwlen,TCHAR *cyphertext,DWORD *ctlen)
{
HCRYPTPROV hProv;
HCRYPTHASH hHash;
HCRYPTKEY hKey;
DWORD dwSizeNeeded =0;
DWORD sz =0;
CryptAcquireContext(&hProv,NULL,MS_STRONG_PROV,PROV_RSA_FULL,0);
CryptCreateHash(hProv,CALG_MD5,0,0,&hHash);
CryptHashData(hHash,(BYTE*)passwd,pwlen,0);
CryptDeriveKey(hProv,CALG_3DES,hHash,0,&hKey);
if(NULL != cyphertext && 0 != ptlen)
{
memcpy(cyphertext,plaintext,ptlen);
sz=*ctlen;
*ctlen=ptlen;
}
if(FALSE == CryptEncrypt(hKey,NULL,1,0,(BYTE *)cyphertext,ctlen,sz))
{
DWORD dwError = GetLastError();
if(ERROR_MORE_DATA == dwError)
{
dwSizeNeeded = *ctlen * sizeof(TCHAR);
}
}
CryptDestroyKey(hKey);
CryptDestroyHash(hHash);
CryptReleaseContext(hProv,0);
return dwSizeNeeded;
}
DWORD TripleDESdecrypt(TCHAR *cyphertext,DWORD ctlen,TCHAR *passwd,DWORD pwlen,TCHAR *plaintext,DWORD *ptlen)
{
HCRYPTPROV hProv;
HCRYPTHASH hHash;
HCRYPTKEY hKey;
DWORD dwSizeNeeded =0;
CryptAcquireContext(&hProv,NULL,MS_STRONG_PROV,PROV_RSA_FULL,0);
CryptCreateHash(hProv,CALG_MD5,0,0,&hHash);
CryptHashData(hHash,(BYTE *)passwd,pwlen,0);
CryptDeriveKey(hProv,CALG_3DES,hHash,0,&hKey);
if(*ptlen >= ctlen)
{
memcpy(plaintext,cyphertext,*ptlen);
CryptDecrypt(hKey,NULL,1,0,(BYTE *)plaintext,&ctlen);
*ptlen=ctlen;
}
else
{
dwSizeNeeded = ctlen * sizeof(TCHAR);
}
CryptDestroyKey(hKey);
CryptDestroyHash(hHash);
CryptReleaseContext(hProv,0);
return dwSizeNeeded;
}
int main()
{
HCRYPTPROV hCryptProv;
HCRYPTHASH hHash = 0;
HCRYPTKEY hKey = 0;
TCHAR szKey[] = _T("key");
TCHAR szUnencrypted[MAX_PATH * sizeof(TCHAR)] = _T("test");
TCHAR * pszEncrypted = NULL;
TCHAR * pszBase64 = NULL;
TCHAR * pszBase64Decoded = NULL;
TCHAR * psz3DESDecoded = NULL;
pszBase64 = Base64Encode((LPCBYTE)&szUnencrypted,_tcslen(szUnencrypted) * sizeof(TCHAR),FALSE);
DWORD dwEncryptedSize = _tcslen(pszBase64);
DWORD dwSizeNeeded = TripleDESencrypt(pszBase64,MAX_PATH * sizeof(TCHAR),szKey,_tcslen(szKey),pszBase64,&dwEncryptedSize);
pszEncrypted = new TCHAR[dwSizeNeeded];
TripleDESencrypt(pszBase64,MAX_PATH * sizeof(TCHAR),szKey,_tcslen(szKey),pszEncrypted,&dwEncryptedSize);
DWORD dwUnEncryptedSize = NULL;
dwSizeNeeded = TripleDESdecrypt(pszEncrypted,dwSizeNeeded,szKey,_tcslen(szKey),szUnencrypted,&dwUnEncryptedSize);
psz3DESDecoded = new TCHAR[dwSizeNeeded];
TripleDESdecrypt(pszEncrypted,dwSizeNeeded,szKey,_tcslen(szKey),psz3DESDecoded,&dwSizeNeeded);
pszBase64Decoded = Base64Decode(psz3DESDecoded,_tcslen(psz3DESDecoded) * sizeof(TCHAR));
MessageBox(NULL,0 == _tcscmp(pszBase64Decoded,szUnencrypted) ? _T("Strings Match"):_T("Strings do NOT Match"),_T(""),MB_OK);
delete [] pszBase64;
delete [] pszBase64Decoded;
delete [] pszEncrypted;
return 0;
}