Click here to Skip to main content
15,892,059 members
Articles / Desktop Programming / MFC

Data encryption with DPAPI

Rate me:
Please Sign up or sign in to vote.
3.73/5 (6 votes)
21 May 2002CPOL4 min read 179.4K   3.9K   44  
A wrapper class for the Data Protection API
// ProtectedDataSample.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "ProtectedDataSample.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#include "../ProtectedData.h"

//---------------------------------------------------------------------------
const static TCHAR chHexTable[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
//---------------------------------------------------------------------------
#define TOHEX(a, b)	{*b++ = chHexTable[a >> 4];*b++ = chHexTable[a&0xf];}

LPCTSTR gTestData = _T("THIS IS A SAMPLE OF USING CPROTECTEDDATA");


void Test1(BOOL b=FALSE);
void Test2(BOOL b=FALSE);
void Test3(BOOL b=FALSE);
void Test4(BOOL b=FALSE);

// The one and only application object

CWinApp theApp;

using namespace std;

int _tmain(void)
{
	int nRetCode = 0;

	// initialize MFC and print and error on failure
	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
	{
		// TODO: change error code to suit your needs
		_tprintf(_T("Fatal Error: MFC initialization failed\n"));
		nRetCode = 1;
	}
	else
	{
		_tprintf(_T("\nTest1(): no UI, no description, no 2nd entropy (passphrase)\n"));
		Test1();

		_tprintf(_T("\nTest2(): no UI, description, no 2nd entropy (passphrase)\n"));
		Test2();

		_tprintf(_T("\nTest3(): no UI, description, 2nd entropy (passphrase)\n"));
		Test3();

		_tprintf(_T("\nAnd now the same with UI enabled\n"));
		_tprintf(_T("\nTest1(): UI, no description, no 2nd entropy (passphrase)\n"));
		Test1(TRUE);

		_tprintf(_T("\nTest2(): UI, description, no 2nd entropy (passphrase)\n"));
		Test2(TRUE);

		_tprintf(_T("\nTest3(): UI, description, 2nd entropy (passphrase)\n"));
		Test3(TRUE);

		_tprintf(_T("\n\nTest4(): no UI, using machine credentials, description, 2nd entropy\n"));
		Test4(TRUE);

	}

	return nRetCode;
}

void Test1(BOOL b)
{
	
	CProtectedData pd(!b);

	if(b)
		pd.SetUI(NULL, _T("CProtectedData Sample Application Test1"));

	_tprintf(_T("Data:\t%s\n"), gTestData);
	pd.SetData((LPBYTE)gTestData, (DWORD)_tcslen(gTestData)+1);
	
	_tprintf(_T("Starting encryption - "));
	const DATA_BLOB* r = pd.ProtectData();		// simple, no description, no UI, no 2nd entropy, no auditing

	if(r->cbData == 0)
	{
		_tprintf(_T("Failed, error: 0x%08x\n"), GetLastError());
	}
	else
	{
		_tprintf(_T("Success\n"));
		LPTSTR p1 = new TCHAR[(r->cbData+1) * 2];
		LPTSTR p = p1;
		for(DWORD i = 0; i < r->cbData; ++i)
		{
			TOHEX(r->pbData[i], p);
		}
		*p=0;
		_tprintf(_T("Result:\t%s\n"), p1);
		delete[] p1;

		// decrypt it again
		{
			CProtectedData upd(!b);

			upd.SetData(r->pbData, r->cbData);

			_tprintf(_T("Starting decryption - "));
			DATA_BLOB* pdata = upd.UnprotectData();
			if(pdata->cbData == 0)
			{
				_tprintf(_T("Failed, error: 0x%08x\n"), GetLastError());
			}
			else
			{
				_tprintf(_T("Success\n"));
				_tprintf(_T("Decrypted Data: %s\n"), pdata->pbData);
				upd.FreeUnprotectedData();
			}
		}

		pd.FreeProtectedData();
	}

}

void Test2(BOOL b)
{
	CProtectedData pd(!b);

	if(b)
		pd.SetUI(NULL, _T("CProtectedData Sample Application Test2"));

	_tprintf(_T("Data:\t%s\n"), gTestData);
	pd.SetData((LPBYTE)gTestData, (DWORD)_tcslen(gTestData)+1);
	
	_tprintf(_T("Starting encryption - "));
	const DATA_BLOB* r = pd.ProtectData(_T("Sample's description"));		// simple, no UI, no 2nd entropy, no auditing

	if(r->cbData == 0)
	{
		_tprintf(_T("Failed, error: 0x%08x\n"), GetLastError());
	}
	else
	{
		_tprintf(_T("Success\n"));
		LPTSTR p1 = new TCHAR[(r->cbData+1) * 2];
		LPTSTR p = p1;
		for(DWORD i = 0; i < r->cbData; ++i)
		{
			TOHEX(r->pbData[i], p);
		}
		*p=0;
		_tprintf(_T("Result:\t%s\n"), p1);
		delete[] p1;

		// decrypt it again
		{
			CProtectedData upd(!b);

			upd.SetData(r->pbData, r->cbData);

			_tprintf(_T("Starting decryption - "));
			LPTSTR pDesc = 0;
			DATA_BLOB* pdata = upd.UnprotectData(&pDesc);
			if(pdata->cbData == 0)
			{
				_tprintf(_T("Failed, error: 0x%08x\n"), GetLastError());
			}
			else
			{
				_tprintf(_T("Success\n"));
				_tprintf(_T("Decrypted Data: %s\n"), pdata->pbData);
				_tprintf(_T("Decrypted Description: %s\n"), pDesc ? pDesc : _T("<none>"));
				upd.FreeUnprotectedData();
				::LocalFree(pDesc);
			}
		}

		pd.FreeProtectedData();
	}

}

void Test3(BOOL b)
{
	CProtectedData pd(!b);

	if(b)
		pd.SetUI(NULL, _T("CProtectedData Sample Application Test3"));

	_tprintf(_T("Data:\t%s\n"), gTestData);
	pd.SetData((LPBYTE)gTestData, (DWORD)_tcslen(gTestData)+1);
	_tprintf(_T("Entropy:\t%s\n"), _T("Well, a passphrase I guess."));
	
	_tprintf(_T("Starting encryption - "));
	const DATA_BLOB* r = pd.ProtectData(_T("Sample's description"), _T("Well, a passphrase I guess."));		// no UI, no auditing

	if(r->cbData == 0)
	{
		_tprintf(_T("Failed, error: 0x%08x\n"), GetLastError());
	}
	else
	{
		_tprintf(_T("Success\n"));
		LPTSTR p1 = new TCHAR[(r->cbData+1) * 2];
		LPTSTR p = p1;
		for(DWORD i = 0; i < r->cbData; ++i)
		{
			TOHEX(r->pbData[i], p);
		}
		*p=0;
		_tprintf(_T("Result:\t%s\n"), p1);
		delete[] p1;

		// decrypt it again
		{
			CProtectedData upd(!b);

			upd.SetData(r->pbData, r->cbData);

			_tprintf(_T("Starting decryption - "));
			LPTSTR pDesc = 0;
			DATA_BLOB* pdata = upd.UnprotectData(&pDesc, _T("Well, a passphrase I guess."));
			if(pdata->cbData == 0)
			{
				_tprintf(_T("Failed, error: 0x%08x\n"), GetLastError());
			}
			else
			{
				_tprintf(_T("Success\n"));
				_tprintf(_T("Decrypted Data: %s\n"), pdata->pbData);
				_tprintf(_T("Decrypted Description: %s\n"), pDesc ? pDesc : _T("<none>"));
				upd.FreeUnprotectedData();
				::LocalFree(pDesc);
			}
		}

		pd.FreeProtectedData();
	}

}

void Test4(BOOL b)
{
	CProtectedData pd(!b, TRUE, TRUE);

	if(b)
		pd.SetUI(NULL, _T("CProtectedData Sample Application Test4"));

	_tprintf(_T("Data:\t%s\n"), gTestData);
	pd.SetData((LPBYTE)gTestData, (DWORD)_tcslen(gTestData)+1);
	_tprintf(_T("Entropy:\t%s\n"), _T("Well, a passphrase I guess."));
	
	pd.SetAudit();

	_tprintf(_T("Starting encryption - "));
	const DATA_BLOB* r = pd.ProtectData(_T("Sample's description"), _T("Well, a passphrase I guess."));		// no UI

	if(r->cbData == 0)
	{
		_tprintf(_T("Failed, error: 0x%08x\n"), GetLastError());
	}
	else
	{
		_tprintf(_T("Success\n"));
		LPTSTR p1 = new TCHAR[(r->cbData+1) * 2];
		LPTSTR p = p1;
		for(DWORD i = 0; i < r->cbData; ++i)
		{
			TOHEX(r->pbData[i], p);
		}
		*p=0;
		_tprintf(_T("Result:\t%s\n"), p1);
		delete[] p1;

		// decrypt it again
		{
			CProtectedData upd(!b);

			upd.SetData(r->pbData, r->cbData);

			_tprintf(_T("Starting decryption - "));
			LPTSTR pDesc = 0;
			DATA_BLOB* pdata = upd.UnprotectData(&pDesc, _T("Well, a passphrase I guess."));
			if(pdata->cbData == 0)
			{
				_tprintf(_T("Failed, error: 0x%08x\n"), GetLastError());
			}
			else
			{
				_tprintf(_T("Success\n"));
				_tprintf(_T("Decrypted Data: %s\n"), pdata->pbData);
				_tprintf(_T("Decrypted Description: %s\n"), pDesc ? pDesc : _T("<none>"));
				upd.FreeUnprotectedData();
				::LocalFree(pDesc);
			}
		}

		pd.FreeProtectedData();
	}

}

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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Portugal Portugal
Software Smith, Blacksmith, Repeat Founder, Austrian, Asgardian.

Comments and Discussions