A fairly common technique among teachers is to show the student how to do something the hard way, to make sure they understand the mechanics of what is going on, and then when they understand that, show them an easier way of doing things.
The Data Protection API (DPAPI) is no different. It provides a simplified API for protecting and unprotecting your data while removing the burden of explicitly generating and managing encryption keys from the developer.
When working with data protection, you need three things:
One thing to keep in mind about the data protection API is that it is not designed for sending secure data from a source to a specific destination. It is designed to allow your application to encrypt data so that the data stored by your application will not be compromised. If you protect data using DPAPI, and then send the data to someone else, they will have no way of decrypting that data.
Both PKCS and DPAPI are extremely powerful encryption tools, but each one has a specific purpose. Knowing when to use PKCS and when to use DPAPI can save you countless hours of rewriting and troubleshooting.
Listing 15.1 is an illustration of how to encrypt and decrypt information using the Data Protection API. Run the code several times to convince yourself that the protection isn't session based and will work every time the protection scope matches the scope of the protected data.
When writing code with the Data Protection API, there are two different kinds of protection that you can use. You can choose to work with protected memory, which turns any array whose length is a multiple of 16 bytes into unreadable gibberish. When you lift the protection on that array, it becomes readable again. The main benefit of this is that when the array is protected, there is nowhere in memory that contains a decrypted copy of that data. This means that malicious attackers examining the memory used by your application or even trying to reverse engineer your application will not be able to locate the protected data in memory.
The second mode of working with the Data Protection API is more traditional. You pass it an array that you want encrypted, an entropy array, and a protection scope. As a return value, you are given an encrypted array of bytes. This method is more suitable for encrypting streams of data, files, and other longer strings. There is also no restriction that the protected data's size be a multiple of 16 as there is with memory protection.
The code in Listing 15.2 illustrates both memory protection and data protection using the Data Protection API.
Listing 15.2. Memory and Data Protection Using DPAPI
Make sure that when you create this application, you also add a reference to the System.Security assembly; otherwise, you won't be able to use the ProtectedMemory class or the DataProtection class.
When you compile and run the application, you will get output that looks like the output shown in Figure 15.3.
Figure 15.3. Output from the data protection sample.