Click here to Skip to main content
15,861,168 members
Articles / Desktop Programming / MFC
Article

Data encryption with DPAPI

Rate me:
Please Sign up or sign in to vote.
3.73/5 (6 votes)
21 May 2002CPOL4 min read 177.6K   3.9K   44   26
A wrapper class for the Data Protection API

Windows Data Protection

DPAPI - Data Protection Application Programming Interface; most probably the smallest API available under Win32. It contains just two functions.

Beginning with Windows 2000, Microsoft introduced the DPAPI. It wasn't well known or documented until Windows XP came out.

The DPAPI is a pretty well thought-out mechanism to allow any application to do simple and yet powerful encryption for its data. It has good recovery methods - in case the password gets lost, fully supports enterprise or home use and is based on the Cryptographic Services available under Win32.

So, what does it actually do?? Simple - it encrypts or decrypts a block of data.

And it does it without asking much for settings, cryptographic keys, algorithms and other hocus-pocus. Sounds like a ideal function for securing sensitive data? Definitely. There are some options that you can set but it goes even without them.

Here are some highlights:

  • user bound encryption (using users credentials)
  • machine bound encryption (using the machines credentials)
  • application supplied pass phrase
  • optional user supplied password
  • transparent mode (no user-interface at all)
  • optional security auditing
  • operating on standards - PKCS#5v2, RFC-2404, RSA etc.

MSDN contains a very well written article explaining the guts of DPAPI and is for sure worth reading if you are into security.

While DPAPI isn't generally difficult to use it has some pitfalls which you can avoid with the CProtectedData class

The class makes all necessary conversions if needed (DPAPI takes only UNICODE strings) and handles filling the data structures, allocating/freeing memory and so on. But at the end its just a wrapper class.

It provides one function in many flavors to perform the encryption and another one for decryption. Sanity checks on parameters are performed.

User interface

As you can see on the pictures, the CryptoAPI provides some dialog boxes with information and options to the user. It allows the user to modify encryption strength, choose a custom password and view information about the data to be encrypted.

Its important to remember when the user is allowed to choose a password, he most probably will forget it. In this case there is no way to retrieve this lost password and the data is not recoverable.

Image 1

The main dialog when the UI is enabled.

Image 2

The "Set security level..." dialog.

Image 3

Changing to High Security mode enables the password. If you don't supply a description, the user can enter a description on his own.

Image 4

The "Details..." dialog.

How to use?

Create an instance of CProtectedData, call its SetData() member function, if needed set some options and finally call one of the ProtectData() or UnprotectData() functions. Both return a pointer to a DATA_BLOB structure. The DATA_BLOB structure contains the size of the resulting data and a pointer to the data. If the cbData member is 0 the encryption/decryption failed and you can call ::GetLastError() to retrieve the reason.

Be aware that this functions may fail when you enable the user interface because the user can cancel the operation while normally the functions succeed.

CProtectedData pd;
pd.SetData(pPlainData, dwPlainDataSize);

const DATA_BLOB* pData = pd.ProtectData();
if(pData->cbData)
    // well, use the data in pData->pbData

For convenience there are two derived classes CUserProtectedData and CMachineProtectedData. While the first is equal to the CProtectedData class, the second class just sets the appropriate option to encrypt with machine credentials. They are just provided for code cleanness.

The DPAPI uses optional entropy data which is supplied by the application. If you supply entropy data, it will - simply expressed - be taken as a part of the password and included in key generation. In other words, it increases security. Data encrypted without entropy data can be decrypted by any other application too.

One last thing is up to you in order to avoid memory leaks: when you retrieve the description string from the encrypted data by supplying UnprotectData() with a pointer to a LPTSTR variable it will place the description into this variable and you must call ::LocalFree() when you don't need it anymore.

Sample Application

The sample application shows how to use any and all of the available options and performs multiple full cycles of encryption/decryption with and without user intervention. Anyway, it does not save the encrypted data to disk.

Compatibility

All classes are fully MBCS/Unicode enabled. The sample contains all configurations. Written, compiled and tested under VC7 but should also compile with VC6 and below. The header file automatically add linking with crypt32.lib. Remember that you need Windows 2000 or Windows XP to use DPAPI.

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

 
QuestionCompiling in MBCS, not UNICODE, gives error [modified] Pin
ehaerim11-Jul-11 19:32
ehaerim11-Jul-11 19:32 
GeneralExtended DPAPI Pin
daves_0513-Mar-11 4:22
daves_0513-Mar-11 4:22 
GeneralFailed encryption And Corrupted decryption [modified] Pin
ehaerim27-Feb-07 9:36
ehaerim27-Feb-07 9:36 
GeneralVS 2005 (VS8) Decrypted Data always returned broken Pin
Amit22034-Feb-07 23:39
Amit22034-Feb-07 23:39 
GeneralRe: VS 2005 (VS8) Decrypted Data always returned broken Pin
ehaerim27-Feb-07 9:41
ehaerim27-Feb-07 9:41 
GeneralRe: VS 2005 (VS8) Decrypted Data always returned broken Pin
Amit220328-Feb-07 10:01
Amit220328-Feb-07 10:01 
QuestionWhat about file size? Pin
esquijarosa29-Dec-04 15:44
esquijarosa29-Dec-04 15:44 
QuestionHow to decrypt on a different machine? Pin
Xavier John12-Nov-03 12:50
Xavier John12-Nov-03 12:50 
AnswerRe: How to decrypt on a different machine? Pin
Andreas Saurwein12-Nov-03 13:14
Andreas Saurwein12-Nov-03 13:14 
GeneralRe: How to decrypt on a different machine? Pin
Xavier John12-Nov-03 15:00
Xavier John12-Nov-03 15:00 
GeneralRe: How to decrypt on a different machine? Pin
Andreas Saurwein13-Nov-03 0:09
Andreas Saurwein13-Nov-03 0:09 
GeneralRe: How to decrypt on a different machine? Pin
Xavier John13-Nov-03 5:58
Xavier John13-Nov-03 5:58 
GeneralRe: How to decrypt on a different machine? Pin
Andreas Saurwein13-Nov-03 6:08
Andreas Saurwein13-Nov-03 6:08 
GeneralBug with wrong entropy code Pin
gmontem30-Sep-03 8:44
gmontem30-Sep-03 8:44 
QuestionHow did you guys run this sample? Pin
Beer10-Dec-02 13:36
Beer10-Dec-02 13:36 
AnswerRe: How did you guys run this sample? Pin
Andreas Saurwein11-Dec-02 1:44
Andreas Saurwein11-Dec-02 1:44 
GeneralRe: How did you guys run this sample? Pin
Beer11-Dec-02 6:28
Beer11-Dec-02 6:28 
GeneralRe: How did you guys run this sample? Pin
Andreas Saurwein11-Dec-02 10:47
Andreas Saurwein11-Dec-02 10:47 
GeneralRe: How did you guys run this sample? Pin
Beer11-Dec-02 11:56
Beer11-Dec-02 11:56 
GeneralRe: How did you guys run this sample? Pin
Anonymous8-Jul-03 5:42
Anonymous8-Jul-03 5:42 
QuestionThanks and ideas on software protection? Pin
dswigger28-May-02 8:26
dswigger28-May-02 8:26 
AnswerRe: Thanks and ideas on software protection? Pin
Andreas Saurwein28-May-02 8:54
Andreas Saurwein28-May-02 8:54 
GeneralRe: Thanks and ideas on software protection? Pin
dswigger28-May-02 9:45
dswigger28-May-02 9:45 
GeneralRe: Thanks and ideas on software protection? Pin
Andreas Saurwein28-May-02 10:04
Andreas Saurwein28-May-02 10:04 
GeneralRe: Thanks and ideas on software protection? Pin
dswigger28-May-02 10:20
dswigger28-May-02 10:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.