howtoconfigurethemachinekeyinaspnet2

Cancel Edit [WikiEntry.PreviewButtonText] Save
Return to ASPNET2SecurityHowTos


How To: Configure MachineKey in ASP.NET 2.0

J.D. Meier, Alex Mackman, Blaine Wastell, Prashant Bansode, Andy Wigley
Microsoft Corporation
May 2005

Applies To

ASP.NET 2.0

Summary

This How To explains how to correctly configure the <machineKey> element for single server and Web farm deployments. You use the <machineKey> to specify keys and algorithms used by ASP.NET to protect Forms authentication tickets and ViewState. In most cases, you should tamper proof ViewState, but avoid storing sensitive data in it so that you do not need to encrypt it. If you intend to store sensitive data in ViewState, then you should enable ViewState encryption. You should tamper proof and encrypt Forms authentication tickets because of the sensitive data, such as role names, stored in the ticket.

Contents

* Overview
* ASP.NET 1.1 <machineKey>
* What's New in ASP.NET 2.0?
* ViewState
* Forms Authentication Tickets
* Web Farm Deployment Considerations
* Additional Resources

Overview

The <machineKey> configuration file element is used to maintain hashing and encryption keys and algorithms. ASP.NET uses these keys to tamper proof and encrypt both Forms authentication tickets and ViewState. This element is stored inside the <system.web> section of either the machine-level Web.config file or an application-specific Web.config file.
Forms authentication tickets and ViewState can be accessed on the client computer and while they cross the network between browser and server. This means they are subject to the following:
* Tampering. An attacker could modify elements of ViewState before posting it back to the server. Depending on how your application uses ViewState, this could result in your application performing unauthorized operations. Similarly, a user could modify an authentication ticket, for example by modifying the list of roles contained in the ticket, to elevate his or her privileges in your application.
* Eavesdropping. An attacker could view sensitive data contained in ViewState or the Forms authentication ticket as it crosses the network or while it is on the client computer. The attacker could use this information to attack your application and the resources it exposes.

ASP.NET provides the following mechanisms to protect ViewState and Forms authentication tickets:
* Hashed Message Authentication Codes (HMACs). With HMAC protection enabled, ASP.NET ensures that ViewState and Forms authentication tickets are tamper proof. Any changes to ViewState or the Forms authentication ticket are detected at the server, and ASP.NET throws an exception if either has been modified.
* Encryption. Encryption turns the clear text data contained in the Forms authentication ticket or ViewState into unintelligible cipher text. This prevents anyone from viewing sensitive data items contained in ViewState or in an authentication ticket.

ASP.NET 1.1 <machineKey>

In ASP.NET 1.1, the <machineKey> element appears in the Machine.config file as shown here:

		 <machineKey 
		   validationKey="xxxx" 	
		   decryptionKey="xxxx"
		   validation="SHA1|MD5|3DES" />
	

The <machineKey> attributes are as follows:
* validationKey. This specifies the key that the HMAC algorithm uses to make ViewState tamper proof. The validationKey is used when either of the following attributes are set to true:

		 <pages enableViewStateMAC="true"> 
		 <@Page EnableViewStateMac="true">
	

* decryptionKey. This specifies the key used to encrypt and decrypt data. Forms authentication uses this key to encrypt and decrypt the authentication ticket. ASP.NET uses the key to encrypt and decrypt ViewState, but only if the validation attribute is set to AES or 3DES.
* validation. This specifies the hashing algorithm used to generate HMACs to prevent tampering with ViewState and the Forms authentication ticket. This attribute is also used to specify the encryption algorithm used for ViewState encryption. This attribute supports the following options:

* SHA1SHA1 is used to tamper proof ViewState and, if configured, the Forms authentication ticket.
* MD5MD5 is used to tamper proof the ViewState and, if configured, the Forms authentication ticket.
* AESAES is used to encrypt ViewState by using the key specified in the decryptionKey attribute.
* 3DES3DES is used to encrypt ViewState by using the key specified in the decryptionKey attribute. This is the only way to encrypt ViewState in ASP.NET version 1.1. Both the Forms authentication ticket and the ViewState are tamper-proofed using SHA-1 and the key specified in the validationKey attribute. Because the validation attribute is overloaded in version 1.1, version 2.0 introduces a new decryption attribute.

In general, you should choose SHA1 over MD5 for tamper-proofing because this produces a larger hash than MD5 and is therefore considered more secure.
Forms authentication defaults to SHA1 for tamper proofing (if <forms protection=”validation” or “All”). When <forms protection=”All”> or <forms protection = “Encryption”>, then Forms authentication hashes the Forms authentication ticket by using either MD5 or HMACSHA1 (HMACSHA1 is used even if validation is set to AES or 3DES). Forms authentication then encrypts the ticket using the algorithm specified in the decryption attribute. The decryption attribute was introduced in ASP.NET 2.0.

What's New in 2.0?

The default settings for the <machineKey> element in ASP.NET 2.0 are defined in Machine.config.comments as shown in Figure 1.


Figure 1 to go here.
Default settings for <machineKey> in ASP.NET 2.0

The decryption attribute is introduced in ASP.NET 2.0. It specifies the symmetric encryption algorithm used to encrypt and decrypt Forms authentication tickets. ASP.NET 2.0 provides support for AES symmetric encryption. Supported values include DES, 3DES, AES and Auto. With Auto, if the value of the decryptionKey attribute is 8 bytes long (16 characters), then Auto defaults to DES. Otherwise, Auto defaults to AES.
The purpose of the validation, validationKey, and decryptionKey attributes is the same as ASP.NET 1.1.
ViewState
You can protect ViewState in the following ways:
* Use an HMAC to make ViewState tamper proof.
* Use encryption to turn ViewState into unintelligible cipher text. This ensures that any sensitive data in ViewState cannot be viewed.

To enable hashing of ViewState, you must use one of the following configurations:

		 <pages enableViewStateMAC="true"> 
	

or

		 <%@Page EnableViewStateMac="true">
	

To enable encryption of ViewState, you must use one of the following configurations:

		 <pages viewStateEncryptionMode="Always">
	

or

		 <%@Page ViewStateEncryptionMode="true">
	

Alternatively, a control on the page must use the Page.RegisterRequiresViewStateEncryption method to request encryption.

Configuring <machineKey> to Tamper Proof ViewState

ViewState is configured for tamper proofing by default. ViewState tamper proofing is enabled by the enableViewStateMac attribute on the <pages> element and the validationKey and validation attributes on the <machineKey> element.

Note: You can see the default <machineKey> setting in the Machine.config.comments file.

To verify that tamper proofing is enabled for ViewState

1. Check that the enableViewStateMac attribute of the <pages> element is set to true, as shown here:

		 <pages enableViewStateMac="true" ... />
	


Note: You can override the machine’s enableViewStateMac setting at the application or page level.


2. Check that the validation attribute of the <machineKey> element is set to SHA1, as shown here:

		 <machineKey …  validation="SHA1" ... />
	

The validation attribute specifies the hashing algorithm used to tamper proof ViewState. The default value is “SHA1”, and you should use this rather than MD5 because it produces a larger hash than MD5 and is therefore considered more secure.
3. Check the validationKey setting of the <machineKey> element.

		 <machineKey validationKey="AutoGenerate,IsolateApps" ... />
	

In the default settings shown above, the AutoGenerate setting instructs ASP.NET to generate a random key. The IsolateApps modifier causes ASP.NET to generate a unique key for each application on your server by using the application ID of each application.
The default value is correct for a single server deployment. You do not need to change the default settings unless your application is deployed in a Web farm. In a Web farm, you must manually generate the validationKey value and make sure that it is the same on all servers in the farm. For more information, see the section “Web Farm Deployment Considerations,” in this document.

Configuring <machineKey> to Encrypt ViewState

By default, information in ViewState is encoded but not encrypted. A user could decode and view the ViewState data.
To encrypt the ViewState, either a control on a page needs to explicitly request ViewState encryption or the viewStateEncryptionMode attribute of the <pages> element must be set to Always. To request encryption, a page must call the RegisterRequiresViewStateEncryption method.
The viewStateEncryptionMode attribute can take one of three possible attributes:
* Auto. This is the default setting, which means the page is only encrypted if a control has specifically asked for it.
* Always. This forces encryption even if a control does not ask for it.
* Never. This disables encryption even if a control does ask for it.

Ideally, you should not store sensitive data in ViewState and thereby avoid the need to encrypt it. If you do need to encrypt ViewState, then you need to specify the encryption algorithm to use on the validation attribute.

To encrypt ViewState

1. Check that the viewStateEncryptionMode attribute of the <pages> element is set to Always, as shown here:

		 <pages ... viewStateEncryptionMode="Always" ... />
	

If you do not want every page to used encrypted ViewState, check that the viewStateEncryptionMode attribute of the <pages> element is set to Auto, as shown here:

		 <pages ... viewStateEncryptionMode="Auto" ... />	
	

Then, from within your code, call the RegisterRequiresViewStateEncryption method as follows:
		 [Page.RegisterRequiresViewStateEncryption();]
	

2. Specify the encryption algorithm to use on the validation attribute, as shown here:

		 <machineKey ... validation="AES" ... />
	

The validation attribute is overloaded and can be used to specify either the hashing algorithm or the encryption algorithm. You can specify either 3DES or AES. (ASP.NET 2.0 introduces support for AES.) Because AES offers larger key sizes (128 bits, 192 bits, or 256 bits) than 3DES (56 bits), it is considered more secure and should be used.
3. Review the decryptionKey attribute of the <machineKey> element:

		 <machineKey decryptionKey="AutoGenerate,IsolateApps" ... />
	

Unless your application is installed in a Web farm, you should leave the decryptionKey attribute with the default values shown in the example. In a Web farm, you must manually generate the decryptionKey value and ensure that its value is the same across all servers in the farm. For more information, see the section, “Web Farm Deployment Considerations,” in this document.

For ViewState encryption, your Machine.config file should resemble the following example:

		 <machineKey 
		    validationKey="AutoGenerate,IsolateApps"   
		    decryptionKey="AutoGenerate,IsolateApps" 
		    validation="AES" 
		    decryption="Auto" />
	


Note: By default ViewState is transmitted as a Base64 encoded string. Although at first glance it is unintelligible, Base64 encoding provides no security because it is easily decoded. If you need to ensure that ViewState contents remain confidential, you must use encryption.

Forms Authentication Tickets

You can protect Forms Authentication tickets in two ways:
* Use an HMAC to make the ticket tamper proof.
* Use encryption to turn the ticket contents into unintelligible cipher text. This ensures that any sensitive data such as role information stored in the ticket cannot be viewed on the client or while the ticket is sent in a cookie between the browser and server.

To ensure that Forms authentication tickets are encrypted and protected against tampering, set the protection attribute of the <forms> element to All, as shown here.

		 <system.web>
		  <authentication mode="Forms">
		    <forms name=".AuthCookie" loginUrl="login.aspx" protection="All"/>
		  </authentication>
		 </system.web>
	

Configuring <machineKey> to Make Forms Authentication Tickets Tamper Proof
To make Forms authentication tickets tamper proof, you use the validationKey and validation attributes of the <machineKey> element.

To review Forms Authentication Ticket configuration for tamper proofing

1. Check that the protection attribute of the <forms> element to All.

		 <forms … protection="All" …/>
	

You can override the protection attribute setting for all Web applications on the server by using the machine level Web.config file or for a specific application by using its Web.config file.
2. Review the validation attribute of the <machineKey> element.

		 <machineKey …  validation="SHA1" … />
	

The validation attribute specifies the hashing algorithm used by the HMAC algorithm used to tamper proof the Forms Authentication ticket. You should use the default SHA1 setting because this produces a larger hash than MD5 and is therefore considered more secure.
You do not need to change the default settings unless your application is deployed in a Web farm. In a Web farm, you must manually generate the validationKey value and make sure that the same value is used across all servers in the farm. For more information, see the section “Web Farm Deployment Considerations” in this document.
3. Review the validationKey attribute of the <machineKey> element.

		 <machineKey validationKey="AutoGenerate,IsolateApps" … />
	

The example configuration shows the default settings. The AutoGenerate setting instructs ASP.NET to generate a random key. The IsolateApps modifier causes ASP.NET to generate a unique key for each application on your server by using the application ID of each application.

Configuring <machineKey> to Encrypt Forms Authentication Tickets

To encrypt Forms authentication tickets, ASP.NET 2.0 uses the decryptionKey and the new decryption attribute of the <machineKey> element. The decryption attribute lets you specify the encryption algorithm to use. ASP.NET 1.1 and 1.0 use 3DES encryption, which is not configurable.

To encrypt Form authentication tickets

1. Check that the protection attribute of the <forms> element is set to All, as shown here:

		 <forms protection="All" …/>
	

2. Use the decryption attribute of the <machineKey> element to specify the encryption algorithm.

		 <machineKey decryption="Auto" … />
	

With the default Auto setting, if the value of the decryptionKey attribute is 8 bytes long (16 characters) then Auto defaults to DES. Otherwise, Auto defaults to AES. ASP.NET 2.0 supports AES, 3DES and DES algorithms. You should use AES because it offers larger key sizes (128 bits, 192 bits, 256 bits) than 3DES (56 bits).
3. Review the decryptionKey attribute of the <machineKey> element.

		 <machineKey decryptionKey="AutoGenerate,IsolateApps" … />
	

Unless your application is installed in a Web farm, you should leave the decryptionKey attribute with the default values shown in the example. In a Web farm, you must manually generate the decryptionKey value and make sure that the same value is used for all servers in the farm. For more information, see the section, “Web Farm Deployment Considerations” in this document.

For Forms authentication ticket encryption, the <machineKey> settings should resemble the following:

		 <machineKey 
		  validationKey="AutoGenerate,IsolateApps" 
		  decryptionKey="AutoGenerate,IsolateApps" 
		  validation="AES" 
		  decryption="Auto" />
	

Web Farm Deployment Considerations

If you deploy your application in a Web farm, you must ensure that the configuration files on each server share hashing and encryption keys. This is required because you cannot guarantee which server will handle successive requests.
With manually generated key values, the <machineKey> settings should be similar to the following:

		 <machineKey   validationKey="21F090935F6E49C2C797F69BBAAD8402ABD2EE0B667A8B44EA7DD4374267A75D7AD972A119482D15A4127461DB1DC347C1A63AE5F1CCFAACFF1B72A7F0A281B"           decryptionKey="261F793EB53B761503AC445E0CA28DA44AA9B3CF06263B77"
		 decryption="3DES"
		 validation="SHA1" />
	

Generate Cryptographically Random Keys

To generate cryptographically random keys:
* Use the RNGCryptoServiceProvider class to generate a cryptographically strong random number.
* Choose an appropriate key size. The recommended key lengths are as follows:
* For SHA1, set the validationKey to 64 bytes (128 hexadecimal characters).
* For AES, set the decryptionKey to 32 bytes (64 hexadecimal characters).
* For 3DES, set the decryptionKey to 24 bytes (48 hexadecimal characters).

The following code shows how to generate random key values. Compile the code to create a console application, and then pass the required key size as a command line argument expressed as the desired number of hexadecimal characters. Each byte is represented by two hexadecimal characters; therefore, to request a 32-byte key, pass 64 as a command line argument. If you do not specify an argument, the code returns a 128 hexadecimal character (64-byte) key.

C# Example

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

		 class App {
		  static void Main(string[] argv) {
		    int len = 128;
		    if (argv.Length > 0)
		      len = int.Parse(argv[0]);
		    byte[] buff = new byte[len/2];
		    [RNGCryptoServiceProvider] rng = new 
		                            [RNGCryptoServiceProvider();]
		    [rng.GetBytes(buff);]
		    [StringBuilder] sb = new [StringBuilder(len);]
		    for (int i=0; i<buff.Length; i++)
		      sb.Append(string.Format("{0:X2}", buff[i]));
		    [Console.WriteLine(sb);]
		  }
		 }
	

Visual Basic Example

		 Imports System
		 Imports System.Text
		 Imports System.Security
		 Imports System.Security.Cryptography
	

		 Module App
		    Sub [Main(ByVal] argv() As String)
		        Dim len As Integer = 128
		        If argv.Length > 0 Then
		            len = Integer.Parse(argv(0))
		        End If
		        Dim buff(len / 2) As Byte
		        Dim rng As New [RNGCryptoServiceProvider()]
		        [rng.GetBytes(buff)]
		        Dim sb As New [StringBuilder(len)]
		        Dim i As Integer
		        For i = 0 To buff.Length - 1
		            sb.Append(String.Format("{0:X2}", buff(i)))
		        Next i
		        [Console.WriteLine(sb)]
		        [Console.ReadLine()]
	

		    End Sub 'Main
		 End Module
	

Run the application twice, and then copy and paste the resulting keys into the <machineKey> element.

Additional Resources

For more information about protecting Forms authentication, see HowToProtectFormsAuth


Return to ASPNET2SecurityHowTos
Microsoft Communities