Yesterday I struggled with finding a way to encrypt a cookie without using Forms Authentication. The problem is that the FormsAuthentification.Encrypt method is using internal methods on the MachineKeySection class.

On the MachineKeySection class there are methods like EncryptOrDecryptData, HexStringToByteArray, ByteArrayToHexString that are all internal. Why make useful functions like these internal?? After some Googling I found this article on codeproject where Eric Newton has made a MachineKeyWrapper that through reflection uses the internal methods to encrypt/decrypt cookie data.

The code in the article does not run on .NET 2.0, you have to update the static constructor of MachineKeyWrapper to this:

static MachineKeyWrapper()
    MachineKeySection config = (MachineKeySection)ConfigurationManager.GetSection("system.web/machineKey");
    Type machineKeyType = config.GetType().Assembly.GetType("System.Web.Configuration.MachineKeySection");

    BindingFlags bf = BindingFlags.NonPublic | BindingFlags.Static;

    Type[] typeArray = new Type[5];
    typeArray.SetValue(typeof(Boolean), 0);
    typeArray.SetValue(typeof(Byte[]), 1);
    typeArray.SetValue(typeof(Byte[]), 2);
    typeArray.SetValue(typeof(Int32), 3);
    typeArray.SetValue(typeof(Int32), 4);

    _encOrDecData = machineKeyType.GetMethod("EncryptOrDecryptData", bf, null, typeArray, null);
    _hexStringToByteArray = machineKeyType.GetMethod("HexStringToByteArray", bf);
    _byteArrayToHexString = machineKeyType.GetMethod("ByteArrayToHexString", bf);

    if (_encOrDecData == null || _hexStringToByteArray == null || _byteArrayToHexString == null)
        throw new InvalidOperationException("Unable to get the methods to invoke.");

It is really irritating when you have discovered a nice solution through Reflector only to find that the class or method that was being used is marked as internal. The .NET framework team is a little too liberal with the internal keyword :)


Kostardiy said...

Look for System.Web.Security.MachineKey class in System.Web assembly of Net 4.0 or newer.