Creating secure applications is more important today than ever before. For ASP.NET developers, sensitive data that resides in configuration files such as Web.config should be protected from prying eyes through encryption. Although the .NET Framework provides a set of cryptography classes, a more elegant and efficient approach is to use the Data Protection API (DPAPI) built into the Windows 2000 and Windows XP operating systems. Let’s see how you can take advantage of the DPAPI in your ASP.NET applications.
Starting with Windows 2000, Microsoft began including an API to perform application-level encryption and decryption of data. This API consists of two functions, CryptProtectData and CryptUnprotectData, exposed by the Crypt32.dll as a part of the Crypto API. These two functions use the time-tested Triple Data Encryption Standard (TripleDES) algorithm to protect data. TripleDES is a symmetric algorithm, meaning that it uses a single secret key for both encryption and decryption.
Since TripleDES requires a key, the DPAPI uses either a key derived from the credentials of the currently logged-on user or a machine-wide key that can be used by any process running on the machine. Although the former is a more secure approach, the latter can be used for server-based applications such as ASP.NET when untrusted users are not allowed to log on to the machine. The key can be optionally augmented with an application-specific secret referred to as secondary entropy.
For more on how the DPAPI uses keys, see “Windows Data Protection” at MSDN.
As you can imagine, the benefits of using the DPAPI are not only that applications get a strong encryption algorithm but also that they don't have to handle, protect, or remember the secret key value.
DPAPI and ASP.NET
So how does this affect ASP.NET developers? In ASP.NET applications, it is a common practice to place application configuration data, such as connection strings and file paths, in the Web.config file placed in the application’s virtual directory. ASP.NET protects this file from HTTP GET requests using an HTTP handler called HttpForbiddenFileHandler, configured in the Machine.config file. But this data should ideally be encrypted, especially if the connection string, for example, contains a user name or password.
To encrypt the data in Web.config, ASP.NET developers often turn to the cryptography classes in the System.Security.Cryptography namespace as described in this Builder.com article. Although these classes expose both symmetric and asymmetric algorithms, they do not provide automatic key management as does the DPAPI. As a result, a simpler approach is to wrap the DPAPI in a managed class that can be called from ASP.NET.
The code to wrap the DPAPI and use it from ASP.NET has been discussed in books such as Writing Secure Code by Michael Howard and David LeBlanc and in articles published on MSDN.
Using the DPAPI in ASP.NET
Although the resources mentioned above provide the base knowledge for using the DPAPI, the code examples are written in C# and are not integrated with the ASP.NET configuration system. To implement the DPAPI in your ASP.NET Web application, you can use the following simple steps.
Download and compile the DataProtector class shown in Listing A in a class library application. This class is the Visual Basic .NET version of the C# code published on MSDN, with several enhancements. First, the DataProtector class is included in the Microsoft.Win32.DPAPI namespace to make it simple to find. Second, I’ve added the overloaded EncryptString and DecryptString methods that work on plain text and base64-encoded strings rather than only on byte arrays. These methods are ideal for reading and writing data to the Web.config file.
Write a small console application that uses the DataProtector class to encrypt the connection string using code like this:
Dim e As String = DataProtector.EncryptString("Application Name=intranet; Password=atomicdoesitbetter;User ID=atomic;Initial Catalog=AtomicDotNet;Data Source=127.0.0.1;", "intranet")
Then, copy the resulting base64-encoded string to the Web.config file and place it in an application-specific configuration section, as shown in Listing B. Note that you’ll need to run the console application on the IIS server to generate the encrypted base64-encoded string. This is because the EncryptString function instructs the DPAPI to use the machine-wide key, so the encryption and decryption will be valid only on the same machine. This is particularly important if you’re running in a Web farm scenario. You’ll notice that the EncryptString function in the snippet above also passes in the secondary entropy value—in this case, the name of the application.
Create a configuration section handler class like that shown in Listing C. This class reads the atomicSettings section of the Web.config file automatically. The class can be registered in the configuration section of the Web.config file like so:
<section name="atomicSettings" type="Atomic.Web.Utils, intranetApp" />
Now, whenever the application is restarted or the Web.config file is changed, the ASP.NET application will invoke the Create method of the Utils class. This method will read the encrypted string from the Web.config file and decrypt it by calling the DataProtector’sDecryptString method. This value will then be exposed to the application via the shared (static) ConnectString property. This way, all the code in the application needs to do to access the connection string is this:
Dim c As String = Atomic.Web.Utils.ConnectString
As a result, the connection string is safely encrypted in Web.config, and yet code in the application is abstracted from the details involved in decrypting this value.
Effectively protect sensitive data
By coupling the ASP.NET configuration system with the DPAPI, ASP.NET developers can effectively and efficiently protect sensitive data such as connection strings stored in the Web.config file.