Using Windows Data Protection


Introduction

Windows Data Protection (or WDP) is an encryption system provided by the operating system based on a key which is automatically generated from the logged-in user's password. It is the system which is used in the background when you call the System.IO.File.Encrypt method on a file.

The same system can also be used in your own applications via the ProtectedData class which resides in the System.Security.Cryptography namespace. A reference to System.Security.dll needs to be added to your project if it is not already present. This class, which wraps the native API functions, also enables a machine-wide key to be generated common to all users of that machine.

WDP provides a moderate amount of protection which depends, of course, on the strength of the user's password. However, security can be improved by using an optional 'entropy' argument which adds some bytes to the key.


Example of usage

For convenience, the following example includes the code to encrypt a file and then decrypt it within the same application using a machine-wide key. The ProtectedData class works at the byte level and so strings need first to be encoded as byte arrays:

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

class Test
{
    static void Main()
    {
        string filePath = "encrypted.txt"; // or whatever you want to call it
        string text = "The quick brown fox jumps over the lazy dog";

        // first encode the string to a byte array using UTF-8
        byte[] original = new UTF8Encoding().GetBytes(text);

        // use machine-wide rather than current user scope
        DataProtectionScope scope = DataProtectionScope.LocalMachine;

        byte[] entropy = new byte[] { 4, 3, 2, 1 }; // this can be anything you like
        byte[] encrypted = ProtectedData.Protect(original, entropy, scope);
        File.WriteAllBytes(filePath, encrypted);
        Console.WriteLine("The file has been created and encrypted. Press any key to decrypt");
        Console.ReadKey(true);

        // recover decrypted data
        byte[] bytes = File.ReadAllBytes(filePath);
        byte[] decrypted = ProtectedData.Unprotect(bytes, entropy, scope);
        string text2 = new UTF8Encoding().GetString(decrypted);
        Console.WriteLine(text2);
        Console.ReadKey(true);
    }
}

The output should, of course, be:

    The quick brown fox jumps over the lazy dog

Conclusion

As mentioned in the Introduction, WDP only affords a moderate level of security and it shouldn't be used if there's any chance that impersonation might be used on the client machine.

However, it does prevent casual inspection of files and sometimes this is all you really need!


Similar Articles