1. 程式人生 > >VC 使用Cryptography 微軟自帶演算法加解密檔案

VC 使用Cryptography 微軟自帶演算法加解密檔案

// Encrypting_a_File.cpp : Defines the entry point for the console 
// application.
//

#include <tchar.h>
#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#include <conio.h>

// Link with the Advapi32.lib file.
#pragma comment (lib, "advapi32")

#define KEYLENGTH  0x00800000
#define ENCRYPT_ALGORITHM CALG_RC4 
#define ENCRYPT_BLOCK_SIZE 8 

bool MyEncryptFile(
	LPTSTR szSource, 
	LPTSTR szDestination, 
	LPTSTR szPassword);

void MyHandleError(
	LPTSTR psz, 
	int nErrorNumber);

//http://msdn.microsoft.com/en-us/library/aa382358.aspx 加密檔案
int _tmain(int argc, _TCHAR* argv[])
{
	if(argc < 3)
	{
		_tprintf(TEXT("Usage: <example.exe> <source file> ")
			TEXT("<destination file> | <password>\n"));
		_tprintf(TEXT("<password> is optional.\n"));
		_tprintf(TEXT("Press any key to exit."));
		_gettch();
		return 1;
	}

	LPTSTR pszSource = argv[1]; 
	LPTSTR pszDestination = argv[2]; 
	LPTSTR pszPassword = NULL;

	if(argc >= 4)
	{
		pszPassword = argv[3];
	}

	//---------------------------------------------------------------
	// Call EncryptFile to do the actual encryption.
	if(MyEncryptFile(pszSource, pszDestination, pszPassword))
	{
		_tprintf(
			TEXT("Encryption of the file %s was successful. \n"), 
			pszSource);
		_tprintf(
			TEXT("The encrypted data is in file %s.\n"), 
			pszDestination);
	}
	else
	{
		MyHandleError(
			TEXT("Error encrypting file!\n"), 
			GetLastError()); 
	}

	return 0;
}

//-------------------------------------------------------------------
// Code for the function MyEncryptFile called by main.
//-------------------------------------------------------------------
// Parameters passed are:
//  pszSource, the name of the input, a plaintext file.
//  pszDestination, the name of the output, an encrypted file to be 
//   created.
//  pszPassword, either NULL if a password is not to be used or the 
//   string that is the password.
bool MyEncryptFile(
	LPTSTR pszSourceFile, 
	LPTSTR pszDestinationFile, 
	LPTSTR pszPassword)
{ 
	//---------------------------------------------------------------
	// Declare and initialize local variables.
	bool fReturn = false;
	HANDLE hSourceFile = INVALID_HANDLE_VALUE;
	HANDLE hDestinationFile = INVALID_HANDLE_VALUE; 

	HCRYPTPROV hCryptProv = NULL; 
	HCRYPTKEY hKey = NULL; 
	HCRYPTKEY hXchgKey = NULL; 
	HCRYPTHASH hHash = NULL; 

	PBYTE pbKeyBlob = NULL; 
	DWORD dwKeyBlobLen; 

	PBYTE pbBuffer = NULL; 
	DWORD dwBlockLen; 
	DWORD dwBufferLen; 
	DWORD dwCount; 

	//---------------------------------------------------------------
	// Open the source file. 
	hSourceFile = CreateFile(
		pszSourceFile, 
		FILE_READ_DATA,
		FILE_SHARE_READ,
		NULL,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL,
		NULL);
	if(INVALID_HANDLE_VALUE != hSourceFile)
	{
		_tprintf(
			TEXT("The source plaintext file, %s, is open. \n"), 
			pszSourceFile);
	}
	else
	{ 
		MyHandleError(
			TEXT("Error opening source plaintext file!\n"), 
			GetLastError());
		goto Exit_MyEncryptFile;
	} 

	//---------------------------------------------------------------
	// Open the destination file. 
	hDestinationFile = CreateFile(
		pszDestinationFile, 
		FILE_WRITE_DATA,
		FILE_SHARE_READ,
		NULL,
		OPEN_ALWAYS,
		FILE_ATTRIBUTE_NORMAL,
		NULL);
	if(INVALID_HANDLE_VALUE != hDestinationFile)
	{
		_tprintf(
			TEXT("The destination file, %s, is open. \n"), 
			pszDestinationFile);
	}
	else
	{
		MyHandleError(
			TEXT("Error opening destination file!\n"), 
			GetLastError()); 
		goto Exit_MyEncryptFile;
	}

	//---------------------------------------------------------------
	// Get the handle to the default provider. 
	if(CryptAcquireContext(
		&hCryptProv, 
		NULL, 
		MS_ENHANCED_PROV, 
		PROV_RSA_FULL, 
		0))
	{
		_tprintf(
			TEXT("A cryptographic provider has been acquired. \n"));
	}
	else
	{
		MyHandleError(
			TEXT("Error during CryptAcquireContext!\n"), 
			GetLastError());
		goto Exit_MyEncryptFile;
	}

	//---------------------------------------------------------------
	// Create the session key.
	if(!pszPassword || !pszPassword[0]) 
	{ 
		//-----------------------------------------------------------
		// No password was passed.
		// Encrypt the file with a random session key, and write the 
		// key to a file. 

		//-----------------------------------------------------------
		// Create a random session key. 
		if(CryptGenKey(
			hCryptProv, 
			ENCRYPT_ALGORITHM, 
			KEYLENGTH | CRYPT_EXPORTABLE, 
			&hKey))
		{
			_tprintf(TEXT("A session key has been created. \n"));
		} 
		else
		{
			MyHandleError(
				TEXT("Error during CryptGenKey. \n"), 
				GetLastError()); 
			goto Exit_MyEncryptFile;
		}

		//-----------------------------------------------------------
		// Get the handle to the exchange public key. 
		if(CryptGetUserKey(
			hCryptProv, 
			AT_KEYEXCHANGE, 
			&hXchgKey))
		{
			_tprintf(
				TEXT("The user public key has been retrieved. \n"));
		}
		else
		{ 
			if(NTE_NO_KEY == GetLastError())
			{
				// No exchange key exists. Try to create one.
				if(!CryptGenKey(
					hCryptProv, 
					AT_KEYEXCHANGE, 
					CRYPT_EXPORTABLE, 
					&hXchgKey))
				{
					MyHandleError(
						TEXT("Could not create a user public key.\n"), 
						GetLastError()); 
					goto Exit_MyEncryptFile;
				}
			}
			else
			{
				MyHandleError(
					TEXT("User public key is not available and may ")
					TEXT("not exist.\n"), 
					GetLastError()); 
				goto Exit_MyEncryptFile;
			}
		}

		//-----------------------------------------------------------
		// Determine size of the key BLOB, and allocate memory. 
		if(CryptExportKey(
			hKey, 
			hXchgKey, 
			SIMPLEBLOB, 
			0, 
			NULL, 
			&dwKeyBlobLen))
		{
			_tprintf(
				TEXT("The key BLOB is %d bytes long. \n"), 
				dwKeyBlobLen);
		}
		else
		{  
			MyHandleError(
				TEXT("Error computing BLOB length! \n"), 
				GetLastError());
			goto Exit_MyEncryptFile;
		}

		if(pbKeyBlob = (BYTE *)malloc(dwKeyBlobLen))
		{ 
			_tprintf(
				TEXT("Memory is allocated for the key BLOB. \n"));
		}
		else
		{ 
			MyHandleError(TEXT("Out of memory. \n"), E_OUTOFMEMORY); 
			goto Exit_MyEncryptFile;
		}

		//-----------------------------------------------------------
		// Encrypt and export the session key into a simple key 
		// BLOB. 
		if(CryptExportKey(
			hKey, 
			hXchgKey, 
			SIMPLEBLOB, 
			0, 
			pbKeyBlob, 
			&dwKeyBlobLen))
		{
			_tprintf(TEXT("The key has been exported. \n"));
		} 
		else
		{
			MyHandleError(
				TEXT("Error during CryptExportKey!\n"), 
				GetLastError());
			goto Exit_MyEncryptFile;
		} 

		//-----------------------------------------------------------
		// Release the key exchange key handle. 
		if(hXchgKey)
		{
			if(!(CryptDestroyKey(hXchgKey)))
			{
				MyHandleError(
					TEXT("Error during CryptDestroyKey.\n"), 
					GetLastError()); 
				goto Exit_MyEncryptFile;
			}

			hXchgKey = 0;
		}

		//-----------------------------------------------------------
		// Write the size of the key BLOB to the destination file. 
		if(!WriteFile(
			hDestinationFile, 
			&dwKeyBlobLen, 
			sizeof(DWORD),
			&dwCount,
			NULL))
		{ 
			MyHandleError(
				TEXT("Error writing header.\n"), 
				GetLastError());
			goto Exit_MyEncryptFile;
		}
		else
		{
			_tprintf(TEXT("A file header has been written. \n"));
		}

		//-----------------------------------------------------------
		// Write the key BLOB to the destination file. 
		if(!WriteFile(
			hDestinationFile, 
			pbKeyBlob, 
			dwKeyBlobLen,
			&dwCount,
			NULL))
		{ 
			MyHandleError(
				TEXT("Error writing header.\n"), 
				GetLastError());
			goto Exit_MyEncryptFile;
		}
		else
		{
			_tprintf(
				TEXT("The key BLOB has been written to the ")
				TEXT("file. \n"));
		}

		// Free memory.
		free(pbKeyBlob);
	} 
	else 
	{ 

		//-----------------------------------------------------------
		// The file will be encrypted with a session key derived 
		// from a password.
		// The session key will be recreated when the file is 
		// decrypted only if the password used to create the key is 
		// available. 

		//-----------------------------------------------------------
		// Create a hash object. 
		if(CryptCreateHash(
			hCryptProv, 
			CALG_MD5, 
			0, 
			0, 
			&hHash))
		{
			_tprintf(TEXT("A hash object has been created. \n"));
		}
		else
		{ 
			MyHandleError(
				TEXT("Error during CryptCreateHash!\n"), 
				GetLastError());
			goto Exit_MyEncryptFile;
		}  

		//-----------------------------------------------------------
		// Hash the password. 
		if(CryptHashData(
			hHash, 
			(BYTE *)pszPassword, 
			lstrlen(pszPassword), 
			0))
		{
			_tprintf(
				TEXT("The password has been added to the hash. \n"));
		}
		else
		{
			MyHandleError(
				TEXT("Error during CryptHashData. \n"), 
				GetLastError()); 
			goto Exit_MyEncryptFile;
		}

		//-----------------------------------------------------------
		// Derive a session key from the hash object. 
		if(CryptDeriveKey(
			hCryptProv, 
			ENCRYPT_ALGORITHM, 
			hHash, 
			KEYLENGTH, 
			&hKey))
		{
			_tprintf(
				TEXT("An encryption key is derived from the ")
				TEXT("password hash. \n")); 
		}
		else
		{
			MyHandleError(
				TEXT("Error during CryptDeriveKey!\n"), 
				GetLastError()); 
			goto Exit_MyEncryptFile;
		}
	} 

	//---------------------------------------------------------------
	// The session key is now ready. If it is not a key derived from 
	// a  password, the session key encrypted with the private key 
	// has been written to the destination file.

	//---------------------------------------------------------------
	// Determine the number of bytes to encrypt at a time. 
	// This must be a multiple of ENCRYPT_BLOCK_SIZE.
	// ENCRYPT_BLOCK_SIZE is set by a #define statement.
	dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE; 

	//---------------------------------------------------------------
	// Determine the block size. If a block cipher is used, 
	// it must have room for an extra block. 
	if(ENCRYPT_BLOCK_SIZE > 1) 
	{
		dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE; 
	}
	else 
	{
		dwBufferLen = dwBlockLen; 
	}

	//---------------------------------------------------------------
	// Allocate memory. 
	if(pbBuffer = (BYTE *)malloc(dwBufferLen))
	{
		_tprintf(
			TEXT("Memory has been allocated for the buffer. \n"));
	}
	else
	{ 
		MyHandleError(TEXT("Out of memory. \n"), E_OUTOFMEMORY); 
		goto Exit_MyEncryptFile;
	}

	//---------------------------------------------------------------
	// In a do loop, encrypt the source file, 
	// and write to the source file. 
	bool fEOF = FALSE;
	do 
	{ 
		//-----------------------------------------------------------
		// Read up to dwBlockLen bytes from the source file. 
		if(!ReadFile(
			hSourceFile, 
			pbBuffer, 
			dwBlockLen, 
			&dwCount, 
			NULL))
		{
			MyHandleError(
				TEXT("Error reading plaintext!\n"), 
				GetLastError());
			goto Exit_MyEncryptFile;
		}

		if(dwCount < dwBlockLen)
		{
			fEOF = TRUE;
		}

		//-----------------------------------------------------------
		// Encrypt data. 
		if(!CryptEncrypt(
			hKey, 
			NULL, 
			fEOF,
			0, 
			pbBuffer, 
			&dwCount, 
			dwBufferLen))
		{ 
			MyHandleError(
				TEXT("Error during CryptEncrypt. \n"), 
				GetLastError()); 
			goto Exit_MyEncryptFile;
		} 

		//-----------------------------------------------------------
		// Write the encrypted data to the destination file. 
		if(!WriteFile(
			hDestinationFile, 
			pbBuffer, 
			dwCount,
			&dwCount,
			NULL))
		{ 
			MyHandleError(
				TEXT("Error writing ciphertext.\n"), 
				GetLastError());
			goto Exit_MyEncryptFile;
		}

		//-----------------------------------------------------------
		// End the do loop when the last block of the source file 
		// has been read, encrypted, and written to the destination 
		// file.
	} while(!fEOF);

	fReturn = true;

Exit_MyEncryptFile:
	//---------------------------------------------------------------
	// Close files.
	if(hSourceFile)
	{
		CloseHandle(hSourceFile);
	}

	if(hDestinationFile)
	{
		CloseHandle(hDestinationFile);
	}

	//---------------------------------------------------------------
	// Free memory. 
	if(pbBuffer) 
	{
		free(pbBuffer); 
	}


	//-----------------------------------------------------------
	// Release the hash object. 
	if(hHash) 
	{
		if(!(CryptDestroyHash(hHash)))
		{
			MyHandleError(
				TEXT("Error during CryptDestroyHash.\n"), 
				GetLastError()); 
		}

		hHash = NULL;
	}

	//---------------------------------------------------------------
	// Release the session key. 
	if(hKey)
	{
		if(!(CryptDestroyKey(hKey)))
		{
			MyHandleError(
				TEXT("Error during CryptDestroyKey!\n"), 
				GetLastError());
		}
	}

	//---------------------------------------------------------------
	// Release the provider handle. 
	if(hCryptProv)
	{
		if(!(CryptReleaseContext(hCryptProv, 0)))
		{
			MyHandleError(
				TEXT("Error during CryptReleaseContext!\n"), 
				GetLastError());
		}
	}

	return fReturn; 
} // End Encryptfile.


//-------------------------------------------------------------------
//  This example uses the function MyHandleError, a simple error
//  handling function, to print an error message to the  
//  standard error (stderr) file and exit the program. 
//  For most applications, replace this function with one 
//  that does more extensive error reporting.

void MyHandleError(LPTSTR psz, int nErrorNumber)
{
	_ftprintf(stderr, TEXT("An error occurred in the program. \n"));
	_ftprintf(stderr, TEXT("%s\n"), psz);
	_ftprintf(stderr, TEXT("Error number %x.\n"), nErrorNumber);
}
// Decrypting_a_File.cpp : Defines the entry point for the console 
// application.
//

#include <tchar.h>
#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#include <conio.h>

// Link with the Advapi32.lib file.
#pragma comment (lib, "advapi32")

#define KEYLENGTH  0x00800000
#define ENCRYPT_ALGORITHM CALG_RC4 
#define ENCRYPT_BLOCK_SIZE 8 

bool MyDecryptFile(
	LPTSTR szSource, 
	LPTSTR szDestination, 
	LPTSTR szPassword);

void MyHandleError(
	LPTSTR psz, 
	int nErrorNumber);
//解密檔案 http://msdn.microsoft.com/en-us/library/aa382044(v=VS.85).aspx
int _tmain(int argc, _TCHAR* argv[])
{
	if(argc < 3)
	{
		_tprintf(TEXT("Usage: <example.exe> <source file> ")
			TEXT("<destination file> | <password>\n"));
		_tprintf(TEXT("<password> is optional.\n"));
		_tprintf(TEXT("Press any key to exit."));
		_gettch();
		return 1;
	}

	LPTSTR pszSource = argv[1]; 
	LPTSTR pszDestination = argv[2]; 
	LPTSTR pszPassword = NULL;

	if(argc >= 4)
	{
		pszPassword = argv[3];
	}

	//---------------------------------------------------------------
	// Call EncryptFile to do the actual encryption.
	if(MyDecryptFile(pszSource, pszDestination, pszPassword))
	{
		_tprintf(
			TEXT("Encryption of the file %s was successful. \n"), 
			pszSource);
		_tprintf(
			TEXT("The encrypted data is in file %s.\n"), 
			pszDestination);
	}
	else
	{
		MyHandleError(
			TEXT("Error encrypting file!\n"), 
			GetLastError()); 
	}

	return 0;
}

//-------------------------------------------------------------------
// Code for the function MyDecryptFile called by main.
//-------------------------------------------------------------------
// Parameters passed are:
//  pszSource, the name of the input file, an encrypted file.
//  pszDestination, the name of the output, a plaintext file to be 
//   created.
//  pszPassword, either NULL if a password is not to be used or the 
//   string that is the password.
bool MyDecryptFile(
	LPTSTR pszSourceFile, 
	LPTSTR pszDestinationFile, 
	LPTSTR pszPassword)
{ 
	//---------------------------------------------------------------
	// Declare and initialize local variables.
	bool fReturn = false;
	HANDLE hSourceFile = INVALID_HANDLE_VALUE;
	HANDLE hDestinationFile = INVALID_HANDLE_VALUE; 
	HCRYPTKEY hKey = NULL; 
	HCRYPTHASH hHash = NULL; 

	HCRYPTPROV hCryptProv = NULL; 

	DWORD dwCount;
	PBYTE pbBuffer = NULL; 
	DWORD dwBlockLen; 
	DWORD dwBufferLen; 

	//---------------------------------------------------------------
	// Open the source file. 
	hSourceFile = CreateFile(
		pszSourceFile, 
		FILE_READ_DATA,
		FILE_SHARE_READ,
		NULL,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL,
		NULL);
	if(INVALID_HANDLE_VALUE != hSourceFile)
	{
		_tprintf(
			TEXT("The source encrypted file, %s, is open. \n"), 
			pszSourceFile);
	}
	else
	{ 
		MyHandleError(
			TEXT("Error opening source plaintext file!\n"), 
			GetLastError());
		goto Exit_MyDecryptFile;
	} 

	//---------------------------------------------------------------
	// Open the destination file. 
	hDestinationFile = CreateFile(
		pszDestinationFile, 
		FILE_WRITE_DATA,
		FILE_SHARE_READ,
		NULL,
		OPEN_ALWAYS,
		FILE_ATTRIBUTE_NORMAL,
		NULL);
	if(INVALID_HANDLE_VALUE != hDestinationFile)
	{
		_tprintf(
			TEXT("The destination file, %s, is open. \n"), 
			pszDestinationFile);
	}
	else
	{
		MyHandleError(
			TEXT("Error opening destination file!\n"), 
			GetLastError()); 
		goto Exit_MyDecryptFile;
	}

	//---------------------------------------------------------------
	// Get the handle to the default provider. 
	if(CryptAcquireContext(
		&hCryptProv, 
		NULL, 
		MS_ENHANCED_PROV, 
		PROV_RSA_FULL, 
		0))
	{
		_tprintf(
			TEXT("A cryptographic provider has been acquired. \n"));
	}
	else
	{
		MyHandleError(
			TEXT("Error during CryptAcquireContext!\n"), 
			GetLastError());
		goto Exit_MyDecryptFile;
	}

	//---------------------------------------------------------------
	// Create the session key.
	if(!pszPassword || !pszPassword[0]) 
	{ 
		//-----------------------------------------------------------
		// Decrypt the file with the saved session key. 

		DWORD dwKeyBlobLen;
		PBYTE pbKeyBlob = NULL;

		// Read the key BLOB length from the source file. 
		if(!ReadFile(
			hSourceFile, 
			&dwKeyBlobLen, 
			sizeof(DWORD), 
			&dwCount, 
			NULL))
		{
			MyHandleError(
				TEXT("Error reading key BLOB length!\n"), 
				GetLastError());
			goto Exit_MyDecryptFile;
		}

		// Allocate a buffer for the key BLOB.
		if(!(pbKeyBlob = (PBYTE)malloc(dwKeyBlobLen)))
		{
			MyHandleError(
				TEXT("Memory allocation error.\n"), 
				E_OUTOFMEMORY); 
		}

		//-----------------------------------------------------------
		// Read the key BLOB from the source file. 
		if(!ReadFile(
			hSourceFile, 
			pbKeyBlob, 
			dwKeyBlobLen, 
			&dwCount, 
			NULL))
		{
			MyHandleError(
				TEXT("Error reading key BLOB length!\n"), 
				GetLastError());
			goto Exit_MyDecryptFile;
		}

		//-----------------------------------------------------------
		// Import the key BLOB into the CSP. 
		if(!CryptImportKey(
			hCryptProv, 
			pbKeyBlob, 
			dwKeyBlobLen, 
			0, 
			0, 
			&hKey))
		{
			MyHandleError(
				TEXT("Error during CryptImportKey!/n"), 
				GetLastError()); 
			goto Exit_MyDecryptFile;
		}

		if(pbKeyBlob)
		{
			free(pbKeyBlob);
		}
	}
	else
	{
		//-----------------------------------------------------------
		// Decrypt the file with a session key derived from a 
		// password. 

		//-----------------------------------------------------------
		// Create a hash object. 
		if(!CryptCreateHash(
			hCryptProv, 
			CALG_MD5, 
			0, 
			0, 
			&hHash))
		{
			MyHandleError(
				TEXT("Error during CryptCreateHash!\n"), 
				GetLastError());
			goto Exit_MyDecryptFile;
		}

		//-----------------------------------------------------------
		// Hash in the password data. 
		if(!CryptHashData(
			hHash, 
			(BYTE *)pszPassword, 
			lstrlen(pszPassword), 
			0)) 
		{
			MyHandleError(
				TEXT("Error during CryptHashData!\n"), 
				GetLastError()); 
			goto Exit_MyDecryptFile;
		}

		//-----------------------------------------------------------
		// Derive a session key from the hash object. 
		if(!CryptDeriveKey(
			hCryptProv, 
			ENCRYPT_ALGORITHM, 
			hHash, 
			KEYLENGTH, 
			&hKey))
		{ 
			MyHandleError(
				TEXT("Error during CryptDeriveKey!\n"), 
				GetLastError()) ; 
			goto Exit_MyDecryptFile;
		}
	}

	//---------------------------------------------------------------
	// The decryption key is now available, either having been 
	// imported from a BLOB read in from the source file or having 
	// been created by using the password. This point in the program 
	// is not reached if the decryption key is not available.

	//---------------------------------------------------------------
	// Determine the number of bytes to decrypt at a time. 
	// This must be a multiple of ENCRYPT_BLOCK_SIZE. 

	dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE; 
	dwBufferLen = dwBlockLen; 

	//---------------------------------------------------------------
	// Allocate memory for the file read buffer. 
	if(!(pbBuffer = (PBYTE)malloc(dwBufferLen)))
	{
		MyHandleError(TEXT("Out of memory!\n"), E_OUTOFMEMORY); 
		goto Exit_MyDecryptFile;
	}

	//---------------------------------------------------------------
	// Decrypt the source file, and write to the destination file. 
	bool fEOF = false;
	do
	{
		//-----------------------------------------------------------
		// Read up to dwBlockLen bytes from the source file. 
		if(!ReadFile(
			hSourceFile, 
			pbBuffer, 
			dwBlockLen, 
			&dwCount, 
			NULL))
		{
			MyHandleError(
				TEXT("Error reading from source file!\n"), 
				GetLastError());
			goto Exit_MyDecryptFile;
		}

		if(dwCount <= dwBlockLen)
		{
			fEOF = TRUE;
		}

		//-----------------------------------------------------------
		// Decrypt the block of data. 
		if(!CryptDecrypt(
			hKey, 
			0, 
			fEOF, 
			0, 
			pbBuffer, 
			&dwCount))
		{
			MyHandleError(
				TEXT("Error during CryptDecrypt!\n"), 
				GetLastError()); 
			goto Exit_MyDecryptFile;
		}

		//-----------------------------------------------------------
		// Write the decrypted data to the destination file. 
		if(!WriteFile(
			hDestinationFile, 
			pbBuffer, 
			dwCount,
			&dwCount,
			NULL))
		{ 
			MyHandleError(
				TEXT("Error writing ciphertext.\n"), 
				GetLastError());
			goto Exit_MyDecryptFile;
		}

		//-----------------------------------------------------------
		// End the do loop when the last block of the source file 
		// has been read, encrypted, and written to the destination 
		// file.
	}while(!fEOF);

	fReturn = true;

Exit_MyDecryptFile:

	//---------------------------------------------------------------
	// Free the file read buffer.
	if(pbBuffer)
	{
		free(pbBuffer);
	}

	//---------------------------------------------------------------
	// Close files.
	if(hSourceFile)
	{
		CloseHandle(hSourceFile);
	}

	if(hDestinationFile)
	{
		CloseHandle(hDestinationFile);
	}

	//-----------------------------------------------------------
	// Release the hash object. 
	if(hHash) 
	{
		if(!(CryptDestroyHash(hHash)))
		{
			MyHandleError(
				TEXT("Error during CryptDestroyHash.\n"), 
				GetLastError()); 
		}

		hHash = NULL;
	}

	//---------------------------------------------------------------
	// Release the session key. 
	if(hKey)
	{
		if(!(CryptDestroyKey(hKey)))
		{
			MyHandleError(
				TEXT("Error during CryptDestroyKey!\n"), 
				GetLastError());
		}
	} 

	//---------------------------------------------------------------
	// Release the provider handle. 
	if(hCryptProv)
	{
		if(!(CryptReleaseContext(hCryptProv, 0)))
		{
			MyHandleError(
				TEXT("Error during CryptReleaseContext!\n"), 
				GetLastError());
		}
	} 

	return fReturn;
}


//-------------------------------------------------------------------
//  This example uses the function MyHandleError, a simple error
//  handling function, to print an error message to the  
//  standard error (stderr) file and exit the program. 
//  For most applications, replace this function with one 
//  that does more extensive error reporting.

void MyHandleError(LPTSTR psz, int nErrorNumber)
{
	_ftprintf(stderr, TEXT("An error occurred in the program. \n"));
	_ftprintf(stderr, TEXT("%s\n"), psz);
	_ftprintf(stderr, TEXT("Error number %x.\n"), nErrorNumber);
}