04/01/2017 by Nitesh

Generate MachineKey using Windows PowerShell

In this post we will see how we can Generate MachineKey using Windows PowerShell from our local development machine.

Problem:
Many a times when a ASP.Net application is running on production server, we get an error message stating – “Validation of viewstate MAC failed. If this application is hosted by a web farm or cluster, ensure that <machineKey> configuration specifies the same validationKey and validation algorithm. AutoGenerate cannot be used in a cluster.” This error happens because of missing machineKey property  in the web.config file.

Overview:
The <machineKey> property in web.config file configures algorithms and keys to use for encryption, decryption, and validation of forms-authentication data and view-state data, and for out-of-process session state identification.This encryption prevents tempering of session data on the server. It is present under <system.web> node in web.config file and looks like below –

<machineKey decryption="AES" decryptionKey="CFCDE8D5806F93E854A74B371BAA279A67D2729DF71A735D0AA3FEDE263C5F59" validation="HMACSHA256" validationKey="9039935908214E31A9705B96C7B2BC93FA966F5FF50748B01FC4F22B24A4149E88298E17B5419E6A054C6FB3883A2C753979A2603F1B85F078DD6383C30CC395" />

N.B: Do not use this machineKey on your production servers. Instead follow the steps mentioned below to generate a new one only for you.

Solution:
We will use a PowerShell script to create this machineKey. Here’s the Powershell Script

# Generates a <machineKey> element that can be copied + pasted into a Web.config file.
function Generate-MachineKey {
  [CmdletBinding()]
  param (
    [ValidateSet("AES", "DES", "3DES")]
    [string]$decryptionAlgorithm = 'AES',
    [ValidateSet("MD5", "SHA1", "HMACSHA256", "HMACSHA384", "HMACSHA512")]
    [string]$validationAlgorithm = 'HMACSHA256'
  )
  process {
    function BinaryToHex {
        [CmdLetBinding()]
        param($bytes)
        process {
            $builder = new-object System.Text.StringBuilder
            foreach ($b in $bytes) {
              $builder = $builder.AppendFormat([System.Globalization.CultureInfo]::InvariantCulture, "{0:X2}", $b)
            }
            $builder
        }
    }
    switch ($decryptionAlgorithm) {
      "AES" { $decryptionObject = new-object System.Security.Cryptography.AesCryptoServiceProvider }
      "DES" { $decryptionObject = new-object System.Security.Cryptography.DESCryptoServiceProvider }
      "3DES" { $decryptionObject = new-object System.Security.Cryptography.TripleDESCryptoServiceProvider }
    }
    $decryptionObject.GenerateKey()
    $decryptionKey = BinaryToHex($decryptionObject.Key)
    $decryptionObject.Dispose()
    switch ($validationAlgorithm) {
      "MD5" { $validationObject = new-object System.Security.Cryptography.HMACMD5 }
      "SHA1" { $validationObject = new-object System.Security.Cryptography.HMACSHA1 }
      "HMACSHA256" { $validationObject = new-object System.Security.Cryptography.HMACSHA256 }
      "HMACSHA385" { $validationObject = new-object System.Security.Cryptography.HMACSHA384 }
      "HMACSHA512" { $validationObject = new-object System.Security.Cryptography.HMACSHA512 }
    }
    $validationKey = BinaryToHex($validationObject.Key)
    $validationObject.Dispose()
    [string]::Format([System.Globalization.CultureInfo]::InvariantCulture,
      "<machineKey decryption=`"{0}`" decryptionKey=`"{1}`" validation=`"{2}`" validationKey=`"{3}`" />",
      $decryptionAlgorithm.ToUpperInvariant(), $decryptionKey,
      $validationAlgorithm.ToUpperInvariant(), $validationKey)
  }
}

You can save this PowerShell script as “generateMachineKey.ps1” on your hard disk. Now open Windows Powershell and perform the following steps –

  • Go to the folder where you have stored the .ps1 filepowershell machineKey aspnet
  • Load the Scriptpowershell machineKey aspnet
  • Call the PowerShell Functionpowershell machineKey aspnet

This will give you a new machineKey. You can copy this and paste it on to your web.config file now.

Hope you like this post.

Was the post helpful? Do let me know if you’re aware of any other way of generating machineKey in comments. Cheers!

 

#IIS#machinekey#Powershell scripts