Skip to content

Instantly share code, notes, and snippets.

@cmcnab
Created March 13, 2017 13:02
Show Gist options
  • Save cmcnab/d2bbed02eb429098ed3656a0729ee40a to your computer and use it in GitHub Desktop.
Save cmcnab/d2bbed02eb429098ed3656a0729ee40a to your computer and use it in GitHub Desktop.
Extracting current ASP.NET machine keys and setting them without committing them to the Web.config
namespace MyApp.Web.Security
{
using System;
using System.Configuration;
using System.Reflection;
using System.Web;
using System.Web.Configuration;
public class MachineKeys
{
public MachineKeys(string encryptionKey, string validationKey)
{
this.EncryptionKey = encryptionKey;
this.ValidationKey = validationKey;
}
public string EncryptionKey { get; }
public string ValidationKey { get; }
public static MachineKeys Extract()
{
var assembly = typeof(HttpRuntime).Assembly; // s_autogenKeys
var typeMKMKP = assembly.GetType("System.Web.Security.Cryptography.MachineKeyMasterKeyProvider");
var typeCK = assembly.GetType("System.Web.Security.Cryptography.CryptographicKey");
var typeCU = assembly.GetType("System.Web.Security.Cryptography.CryptoUtil");
var config = new MachineKeySection();
var mkmkp = assembly.CreateInstance(typeMKMKP.FullName, false, BindingFlags.Instance | BindingFlags.NonPublic, null, new object[] { config, null, null, null, null }, null, null);
var encKey = typeMKMKP.GetMethod("GetEncryptionKey").Invoke(mkmkp, Array.Empty<object>());
var valKey = typeMKMKP.GetMethod("GetValidationKey").Invoke(mkmkp, Array.Empty<object>());
var methodGetKeyMaterial = typeCK.GetMethod("GetKeyMaterial");
Func<object, byte[]> getKeyMaterial = k => (byte[])methodGetKeyMaterial.Invoke(k, Array.Empty<object>());
var methodBinaryToHex = typeCU.GetMethod("BinaryToHex");
Func<byte[], string> binaryToHex = d => (string)methodBinaryToHex.Invoke(null, new object[] { d });
return new MachineKeys(
binaryToHex(getKeyMaterial(encKey)),
binaryToHex(getKeyMaterial(valKey)));
}
public static void InstallKeysFromAppSettings()
{
Install(GetKeysFromAppSettings());
}
public static void Install(MachineKeys keys)
{
if (keys == null)
{
return;
}
var getter = typeof(MachineKeySection).GetMethod("GetApplicationConfig", BindingFlags.Static | BindingFlags.NonPublic);
var config = (MachineKeySection)getter.Invoke(null, Array.Empty<object>());
var readOnlyField = typeof(ConfigurationElement).GetField("_bReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
readOnlyField.SetValue(config, false);
config.DecryptionKey = keys.EncryptionKey;
config.ValidationKey = keys.ValidationKey;
readOnlyField.SetValue(config, true);
}
public static MachineKeys GetKeysFromAppSettings()
{
var encKey = ConfigurationManager.AppSettings["machineDecryptionKey"];
if (string.IsNullOrEmpty(encKey))
{
return null;
}
var valKey = ConfigurationManager.AppSettings["machineValidationKey"];
if (string.IsNullOrEmpty(valKey))
{
return null;
}
return new MachineKeys(encKey, valKey);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment