Click here to Skip to main content
15,896,557 members
Articles / Desktop Programming / ATL

How to use Crypto API in your ASP projects.

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
28 Aug 20013 min read 271.3K   1.2K   53  
This article shows how to make one ATL COM component with crypt/decrypt functions and how to use it in ASP programs. It shows also how to register a component in MTS.
// Encryption.cpp : Implementation of CEncryption
#include "stdafx.h"
#include "EncryptionATL.h"
#include "Encryption.h"

//#include <windows.h>
//#include <tchar.h>
//#include <stdio.h>
#include <Wincrypt.h>
#include <comdef.h>

/////////////////////////////////////////////////////////////////////////////
// CEncryption

STDMETHODIMP CEncryption::InterfaceSupportsErrorInfo(REFIID riid)
{
	static const IID* arr[] = 
	{
		&IID_IEncryption
	};
	for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
		if (InlineIsEqualGUID(*arr[i],riid))
			return S_OK;
	}
	return S_FALSE;
}

////////////////////////////////////////////////////
unsigned char BtoH(char ch) 
{     
	if (ch >= '0' && ch <= '9') return (ch - '0');		// Handle numerals     
	if (ch >= 'A' && ch <= 'F') return (ch - 'A' + 0xA);  // Handle capitol hex digits     
	if (ch >= 'a' && ch <= 'f') return (ch - 'a' + 0xA);  // Handle small hex digits     
	return(255); 
}  

void AtoH(char * src, char * dest, int destlen) 
{
	char * srcptr;      
	srcptr = src;      
	while(destlen--)     
	{     
		//*dest = BtoH(*srcptr++) << 4;    // Put 1st ascii byte in upper nibble.     
		*dest = BtoH(*srcptr++) << 4;
		*dest++ += BtoH(*srcptr++);      // Add 2nd ascii byte to above.     
	} 
}  

char HtoB(UCHAR ch) 
{     
	if (ch <= 9) return ('0' + ch);             // handle decimal values     
	if (ch <= 0xf) return ('A' + ch - 10);      // handle hexidecimal specific values     
	return('X');                                // Someone screwed up 
} 

void HtoA(char * src, char * dest, int srclen) 
{    
	char * destptr; // temp pointers     
	UCHAR * srcptr;              
	srcptr = (UCHAR *)src;     
	destptr = dest;      
	while(srclen--)     
	{     
		*destptr++ = HtoB((UCHAR)(*srcptr >> 4));      // Convert high order nibble     
		*destptr++ = HtoB((UCHAR)(*srcptr++ & 0x0F));  // Convert low order nibble     
	}     
	*destptr = 0;  // Null terminator 
}  

////////////////////////////////////////////////////////
//******************************************************

BOOL CEncryption::MyCrypt(TCHAR* szPassword)
{	
	

	BOOL bResult = TRUE;	
	 
	HCRYPTPROV hProv = NULL;	
	HCRYPTKEY hKey = NULL;
	HCRYPTKEY hXchgKey = NULL;	
	HCRYPTHASH hHash = NULL;	
	DWORD dwLength;
	// Used to encrypt the real password	
	TCHAR szLocalPassword[] = _T("Mz6@a0i*");
	// Get handle to user default provider.
	if (CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))	
	{
	
		// Create hash object.		
		if (CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))		
		{
			
			// Hash password string.			
			dwLength = sizeof(TCHAR)*_tcslen(szLocalPassword);
			if (CryptHashData(hHash, (BYTE *)szLocalPassword, dwLength, 0))			
			{
			
				// Create block cipher session key based on hash of the password.
				if (CryptDeriveKey(hProv, CALG_RC4, hHash, CRYPT_EXPORTABLE, &hKey))				
				{
					// Determine number of bytes to encrypt at a time.
					dwLength = sizeof(TCHAR)*_tcslen(szPassword);	
					if (dwLength<=16)
					{
						// Allocate memory.
						BYTE *pbBuffer = (BYTE *)malloc(dwLength);					
						if (pbBuffer != NULL)					
						{
							memcpy(pbBuffer, szPassword, dwLength);		
							
							
							// Encrypt data
							if (CryptEncrypt(hKey, 0, TRUE, 0, pbBuffer, &dwLength, dwLength)) 						
							{
								// Write data to registry.							
								//pbBuffer, dwLength
								//_tcscpy(basket, (char *)pbBuffer);
								
								//basket	= (LPCTSTR)pbBuffer;
								_tcscpy(szPassword, _T(""));
								
								char  dest[32];
								//char	*dest;
								memcpy(dest, pbBuffer, dwLength);
								sprintf( dest + dwLength, "\0");
								
								//acu transform in hexa rezultatul	
								HtoA(dest, szPassword, sizeof(TCHAR)*_tcslen(dest) );
							}	
							else						
							{	
								long err	= GetLastError ();
								char BUFF[100];
								FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, BUFF, 100, NULL);
								m_sLastError	= CString(BUFF);
								bResult = FALSE;						
							}						
							// Free memory.
							free(pbBuffer);					
						}
						else					
						{		
							long err	= GetLastError ();
							char BUFF[100];
							FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, BUFF, 100, NULL);
							m_sLastError	= CString(BUFF);
							bResult = FALSE;					
						}
						CryptDestroyKey(hKey);  // Release provider handle.				
					}
					else
					{
						m_sLastError	= "The string must have maxim 16 characters";
						bResult = FALSE;
					}
				}				
				else				
				{
					// Error during CryptDeriveKey!					
					long err	= GetLastError ();
					char BUFF[100];
					FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, BUFF, 100, NULL);
					m_sLastError	= CString(BUFF);
					bResult = FALSE;				
				}			
			}			
			else			
			{
				// Error during CryptHashData!				
				long err	= GetLastError ();
				char BUFF[100];
				FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, BUFF, 100, NULL);
				m_sLastError	= CString(BUFF);
				bResult = FALSE;			
			}
			CryptDestroyHash(hHash); 
			// Destroy session key.		
		}		
		else		
		{
			// Error during CryptCreateHash!	
			long err	= GetLastError ();
			char BUFF[100];
			FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, BUFF, 100, NULL);
			m_sLastError	= CString(BUFF);
			bResult = FALSE;		
		}
		CryptReleaseContext(hProv, 0);	
	}	
	else
	{
		// Error during AcquireContext!			
		long err	= GetLastError ();
		char BUFF[100];
		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, BUFF, 100, NULL);
		m_sLastError	= CString(BUFF);
		bResult = FALSE;		
	}
	return bResult;
}


BOOL CEncryption::MyDecrypt(TCHAR* szPassword) 
{	
	BOOL bResult = TRUE;	
	
	
	HCRYPTPROV hProv = NULL;		
	HCRYPTKEY hKey = NULL;		
	HCRYPTKEY hXchgKey = NULL;
	HCRYPTHASH hHash = NULL;		
	DWORD dwLength;
	// has to be the same used to encrypt!
	TCHAR szLocalPassword[] = _T("Mz6@a0i*");
	// Get handle to user default provider.
	if (CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))		
	{
		// Create hash object.			
		if (CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
		{				
			// Hash password string.
			dwLength = sizeof(TCHAR)*_tcslen(szLocalPassword);
			if (CryptHashData(hHash, (BYTE *)szLocalPassword, dwLength, 0))				
			{
				// Create block cipher session key based on hash of the password.
				if (CryptDeriveKey(hProv, CALG_RC4, hHash, CRYPT_EXPORTABLE, &hKey))					
				{
					// the password is less than 32 characters
					dwLength = 32*sizeof(TCHAR);						
					
					//(BYTE*)szPassword

					//tre sa desfac hexa
					TCHAR dest[32];
					dwLength = sizeof(TCHAR)*_tcslen(szPassword);
						
					if (dwLength<=32)
					{				
						AtoH(szPassword, dest, dwLength/2 );	
						dest[dwLength/2]	= '\0';

						_tcscpy(szPassword, dest);
						//_tprintf( szPassword + dwLength/2, "\0");			
						
						dwLength = sizeof(TCHAR)*_tcslen(szPassword);
						if (!CryptDecrypt(hKey, 0, TRUE, 0, (BYTE *)szPassword, &dwLength))
						{
							long err	= GetLastError ();
							char BUFF[100];
							FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, BUFF, 100, NULL);
							m_sLastError	= CString(BUFF);
							bResult = FALSE;											
						}
						
						CryptDestroyKey(hKey);  // Release provider handle.					
					}
					else
					{
						m_sLastError	= "The string must have maxim 16 characters";
						bResult = FALSE;
					}
				}					
				else					
				{
					// Error during CryptDeriveKey!			
					long err	= GetLastError ();
					char BUFF[100];
					FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, BUFF, 100, NULL);
					m_sLastError	= CString(BUFF);
					bResult = FALSE;					
				}				
			}				
			else
			{					
				// Error during CryptHashData!				
				long err	= GetLastError ();
				char BUFF[100];
				FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, BUFF, 100, NULL);
				m_sLastError	= CString(BUFF);
				bResult = FALSE;				
			}
			CryptDestroyHash(hHash); // Destroy session key.			
		}			
		else			
		{
			// Error during CryptCreateHash!				
			long err	= GetLastError ();
			char BUFF[100];
			FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, BUFF, 100, NULL);
			m_sLastError	= CString(BUFF);
			bResult = FALSE;			
		}
		CryptReleaseContext(hProv, 0);		
	}		
	else
	{
		long err	= GetLastError ();
		char BUFF[100];
		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, BUFF, 100, NULL);
		m_sLastError	= CString(BUFF);
		bResult = FALSE;			
	}
	
	return bResult;
}

//******************************************************

CString CEncryption::GetTime()
{
	CString MyStrTime;
	CTime theTime;
	theTime = CTime::GetCurrentTime();
	MyStrTime	= theTime.Format("time: %H:%M:%S:%u");
	return MyStrTime;
}

//******************************************************

STDMETHODIMP CEncryption::LastError(BSTR *parOut)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState())

	*parOut		= _bstr_t((LPCTSTR)m_sLastError).copy();

	return S_OK;
}

STDMETHODIMP CEncryption::Crypt(BSTR parIn, BSTR *parOut)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState())

	m_sLastError.Empty();

	_tcscpy(m_sBasket, CString(parIn));

	if (!MyCrypt(m_sBasket))
	{
		//m_sLastError	+= "Crypting error !!!";
		return S_OK;
	}
	else
	{
		m_sLastError	= "OK";

		*parOut		= _bstr_t((LPCTSTR)m_sBasket).copy();
		return S_OK;
	}

}

STDMETHODIMP CEncryption::Decrypt(BSTR parIn, BSTR *parOut)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState())

	m_sLastError.Empty();

	_tcscpy(m_sBasket, CString(parIn));

	if (!MyDecrypt(m_sBasket))
	{
		//m_sLastError	= "Decrypting error !!!";
		return S_OK;
	}
	else
	{
		m_sLastError	= "OK";
		*parOut		= _bstr_t((LPCTSTR)m_sBasket).copy();
		return S_OK;
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Romania Romania
I make programming for over 4 years and extensive experience in C++, ASP, Pascal, MFC, COM+, ATL, TCP/IP, HTTP protocols, XML, XSL, SOAP and SQL.
For the last 2 years i working extensively at the background of financial sites (databases, n tier architecture).

I’m available for contracts and/or outsourcing (<Adrian Bacaianu>adrian_bacaianu@yahoo.com).

Comments and Discussions