The <machineKey> Element configures keys to use for encryption and decryption of forms authentication cookie data and viewstate data, and for verification of out-of-process session state identification. This section can be declared at the machine, site, and application levels, but not at the subdirectory level. For anybody that's running ASP.NET on a server farm, the <machineKey> element is one of those guys you want to know as much as you can about IN ADVANCE - before you run into problems!

 

 

Here is an example Configuration Structure for the element:

<configuration>
<system.web>
<machineKey><machineKey validationKey="AutoGenerate|value[,IsolateApps]"
decryptionKey="AutoGenerate|value[,IsolateApps]
validation="SHA1|MD5|3DES"/>


The validationKey attribute specifies the key used for validation of encrypted data. validationKey is used when enableViewStateMAC is true to create a message authentication code (MAC) to ensure that view state has not been tampered with. ValidationKey is also used to generate out-of-process, application-specific session IDs to ensure that session state variables are isolated between sessions.

AutoGenerate specifies that ASP.NET generates a random key and stores it in the Local Security Authority (LSA). The AutoGenerate option is the default value, but you definitely DON'T want this for a web farm! If you add the IsolateApps modifier to the validationKey value, ASP.NET generates a unique encrypted key for each application using each application's application ID. For a web farm, you want to manually put in your own keys and make sure they are EXACTLY THE SAME on each machine in the farm.

The value attribute specifies a manually assigned validation key. This value must be manually set to ensure consistent configuration across a network of Web servers (a Web farm). The key must be a minimum of 40 characters (20 bytes) and a maximum of 128 characters (64 bytes) long. If keys shorter than the maximum length are used, they should be created by a truly random means, such as by using RNGCryptoServiceProvider, which we will show below. The recommended key length is 128 hexadecimal characters. If you add the IsolateApps modifier to the validationKey value, ASP.NET generates a unique encrypted key for each application using each application's application ID.


The decryptionKey attribute specifies the key used to encrypt data. decryptionKey is used for Forms authentication encryption and decryption and for view state encryption when validation is 3DES.


The AutoGenerate attribute for decryptionKey specifies that ASP.NET generates a random key and stores it in the LSA. The AutoGenerate option is the default value. If you add the IsolateApps modifier to the decryptionKey value, ASP.NET generates a unique encrypted key for each application using each application's application ID.


The value attribute for decryptionKey specifies a manually assigned key. This value must be manually set to a string of hexadecimal characters to ensure consistent configuration across a Web farm. The key should be 16 characters in length when using DES encryption and 48 characters in length when using Triple DES encryption. If keys shorter than the maximum length are used, they should be created by a truly random means. ASP.NET can use Triple DES only on computers on which 128-bit encryption is available. If you add the IsolateApps modifier to the decryptionKey value, ASP.NET generates a unique encrypted key for each application using each application's application ID.


validation specifies the type of encryption used for validation of data:

  • SHA1 specifies that ASP.NET uses SHA1 encryption.
  • MD5 specifies that ASP.NET uses MD5 encryption.
  • 3DES specifies that ASP.NET uses Triple-DES (3DES) encryption. When 3DES is specified, forms authentication defaults to SHA1. When the validation attribute is set to 3DES, the view state validation technique uses 3DES encryption.

In order to use the above as a programming exercise to provide something useful, I've created a WebForm that creates the entire <machineKey> element so that you can copy it to the clipboard and paste it into the machine.config (or other config) file of each server on your farm. Yay! No more corrupted viewState and other nasty messages that you couldn't figure out until you were lucky enough to land on this page! Enjoy.




The WebForm1.Aspx fle:

<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false"
Inherits="GenerateMachineKey.WebForm1" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>WebForm1</title>
<meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
<meta name="CODE_LANGUAGE" Content="C#">
<meta name="vs_defaultClientScript" content="JavaScript">
<meta name="vs_targetSchema"
content="http://schemas.microsoft.com/intellisense/ie5">
<script>
function clipCopy(strElem){
strElem.focus();
strElem.select();
window.clipboardData.setData('Text', strElem.value);
}

</script>
</HEAD>
<body MS_POSITIONING="GridLayout">
<form id="Form1" method="post" runat="server">
<asp:TextBox id="TextBox1" style="Z-INDEX: 101; LEFT: 24px;
POSITION: absolute; TOP: 176px" runat="server"
Width="784px" Height="88px" TextMode="MultiLine"></asp:TextBox>
<asp:Label id="Label1" style="Z-INDEX: 102; LEFT: 288px;
POSITION: absolute; TOP: 56px" runat="server"
Width="328px" Height="48px" Font-Names="Comic Sans MS"
Font-Size="Larger">Pete's Nifty Machine Key Generator</asp:Label>
<asp:Button id="Button1" style="Z-INDEX: 103; LEFT: 192px;
POSITION: absolute; TOP: 280px" runat="server"
Width="208px" Text="Generate Me A Key!"></asp:Button>
<INPUT style="Z-INDEX: 104; LEFT: 448px; WIDTH: 200px;
POSITION: absolute; TOP: 280px; HEIGHT: 24px"
type="button" value="Copy to Clipboard" onclick="clipCopy(TextBox1);">
</form>
</body>
</HTML>
'

The Webform1.aspx.cs File:

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Security.Cryptography;
using System.IO;
using System.Text;


namespace GenerateMachineKey
{
/// <summary>
/// Summary description for WebForm1.
/// </summary>
public class WebForm1 : System.Web.UI.Page
{
private void Page_Load(object sender, System.EventArgs e)
{

}
// generates a random <machineKey> element that you can use
// to replace the existing one in your machine.config file
// useful for synchronization of the ASP.NET encryption and
// validation keys in your web farm


static RNGCryptoServiceProvider srng = new RNGCryptoServiceProvider();

// 64 bytes is max size supported by ASP.NET
const int validationKeyLength = 64;
protected System.Web.UI.WebControls.TextBox TextBox1;
protected System.Web.UI.WebControls.Label Label1;
protected System.Web.UI.WebControls.Button Button1;

// 24 bytes is max size supported by ASP.NET (3DES)
const int decryptionKeyLength = 24;

static string GenerateKey(){

StringBuilder sb = new StringBuilder();
sb.Append("<machineKey validationKey='");

sb.Append( writeKeyAsHexDigits(getRandom(validationKeyLength)));

sb.Append("'");
sb.Append(" decryptionKey='");

sb.Append(writeKeyAsHexDigits(getRandom(decryptionKeyLength)));

sb.Append("'");
sb.Append(" validation='SHA1'/>");
return sb.ToString();
}
static byte[] getRandom(int cb)
{
byte[] randomData = new byte[cb];
srng.GetBytes(randomData);
return randomData;
}
static string writeKeyAsHexDigits(byte[] key)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < key.Length; ++i)
{

sb.Append( String.Format("{0:X2}", key[i]));

}
return sb.ToString();
}



#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}
private void InitializeComponent()
{
this.Button1.Click += new System.EventHandler(this.Button1_Click);
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion

private void Button1_Click(object sender, System.EventArgs e)
{
TextBox1.Text =GenerateKey();

}
}
}
And true to form, if you are just too lazy to download and play with the code and you want to try it out online, I just happen to have my free GenerateMachineKey page working right over here. The Visual Studio.NET 2003 solution zip file can be downloaded below (if you don't have VS.NET 2003, just start an empty web project and add the files to it).
posted on 2011-01-28 20:13  cwe  阅读(518)  评论(0编辑  收藏  举报