Skip to content

Instantly share code, notes, and snippets.

@lennybacon
Last active October 16, 2019 09:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lennybacon/263fd6ee02f7dcfcc6a3d2f48db59249 to your computer and use it in GitHub Desktop.
Save lennybacon/263fd6ee02f7dcfcc6a3d2f48db59249 to your computer and use it in GitHub Desktop.
Machine Key Section validation and decryption key rotation on build
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask
TaskName="GenerateMachineKey"
TaskFactory="CodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
<ParameterGroup />
<Task>
<Reference Include="System.Xml"/>
<Using Namespace="System"/>
<Using Namespace="System.IO"/>
<Using Namespace="System.Reflection"/>
<Using Namespace="System.Xml"/>
<Using Namespace="System.Security.Cryptography"/>
<Code Type="Fragment" Language="cs">
<![CDATA[
var fileName = ".\\Web.Config";
var xmlDoc = new XmlDocument();
xmlDoc.Load(fileName);
var configurationNode = xmlDoc.SelectSingleNode("/configuration");
if (configurationNode == null)
{
Log.LogMessage(
"Cannot find configuration - Create it...",
MessageImportance.High);
configurationNode = xmlDoc.CreateElement("configuration");
//xmlDoc.DocumentElement.AppendChild(configurationNode);
}
var systemWebNode = xmlDoc.SelectSingleNode("/configuration/system.web");
if (systemWebNode == null)
{
Log.LogMessage(
"Cannot find system.web - Create it...",
MessageImportance.High);
systemWebNode = xmlDoc.CreateElement("system.web");
configurationNode.AppendChild(systemWebNode);
}
var machineKeyNode =
xmlDoc.SelectSingleNode("/configuration/system.web/machineKey")
as XmlElement;
if (machineKeyNode == null)
{
Log.LogMessage(
"Cannot find machineKey - Create it...",
MessageImportance.High);
machineKeyNode = xmlDoc.CreateElement("machineKey");
systemWebNode.AppendChild(machineKeyNode);
}
machineKeyNode.Attributes.RemoveAll();
machineKeyNode.SetAttribute(
"validation",
"HMACSHA512");
machineKeyNode.SetAttribute(
"decryption",
"AES");
var rng = new RNGCryptoServiceProvider();
var validationKey = new byte[64];
rng.GetBytes(validationKey);
machineKeyNode.SetAttribute(
"validationKey",
string.Join("", validationKey.Select(x => x.ToString("x2"))));
var decryptionKey = new byte[16];
rng.GetBytes(decryptionKey);
machineKeyNode.SetAttribute(
"decryptionKey",
string.Join("", decryptionKey.Select(x => x.ToString("x2"))));
Log.LogMessage(
"Updated decryption key and validation key of machineKey section",
MessageImportance.High);
xmlDoc.Save(fileName);
]]>
</Code>
</Task>
</UsingTask>
<Target Name="GenerateMachineKeyPreTransformWebConfig" BeforeTargets="PreTransformWebConfig">
<Message Text="GenerateMachineKeyPreTransformWebConfig" Importance="High" />
<GenerateMachineKey Condition="'$(Configuration)' == 'Release'" />
</Target>
</Project>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment