diff --git a/README.md b/README.md index 621efe4..866d1dd 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,11 @@ httpsecurecookie Store encrypted data within encoded cookies for use in server-side implementations without requiring sessions. +> Note: 0.2 version of the assembly uses new .NET machine key api. +> Use NET40 compiler constant to target 4.0 encode/decode pair (obsolete, but works). +> Use NET45 compiler constant to target 4.5 protect/unprotect pair. +> Delta code added by Keyur, Infosys. + I originally wrote about the need for encrypted cookies a while back, 2006 to be accurate: http://www.codeproject.com/Articles/8742/Encrypting-Cookies-to-prevent-tampering diff --git a/src/AssemblyInfo.cs b/src/AssemblyInfo.cs index dcba110..e71e871 100644 --- a/src/AssemblyInfo.cs +++ b/src/AssemblyInfo.cs @@ -5,13 +5,15 @@ // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. +// There is no connection between Eric and Infosys. +// The delta code has been modified by me -Keyur. // [assembly: AssemblyTitle("HttpCookieEncryption")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("ericnewton76")] +[assembly: AssemblyCompany("ericnewton76 AndAlso Infosys")] [assembly: AssemblyProduct("HttpCookieEncryption")] -[assembly: AssemblyCopyright("Copyright(C) 2012, ericnewton76")] +[assembly: AssemblyCopyright("Copyright(C) 2012, ericnewton76 AndAlso 2016, Infosys/keyurpd")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -25,5 +27,5 @@ // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("0.1.0.0")] -[assembly: AssemblyFileVersion("0.1.1.15813")] +[assembly: AssemblyVersion("0.2.0.0")] +[assembly: AssemblyFileVersion("0.2.1.15813")] diff --git a/src/HttpCookieEncryption.cs b/src/HttpCookieEncryption.cs index ba9f03c..ec930f5 100644 --- a/src/HttpCookieEncryption.cs +++ b/src/HttpCookieEncryption.cs @@ -1,3 +1,7 @@ +///Edited from original project at https://github.com/ericnewton76/httpsecurecookie +///Defined new build constants, NET20 || NET30 || NET35 +///30Mar16, Keyur Desai, Infosys + using System; using System.Web; using System.Web.Configuration; @@ -25,7 +29,8 @@ public static HttpCookie Decrypt(HttpCookie cookie) if(cookie.Value.Length==0) return cookie; try - { + { +#if NET10 || NET11 || NET20 || NET30 || NET35 byte[] encrypted = MachineKeyWrapper.HexStringToByteArray(cookie.Value); if (encrypted == null) return null; // i wonder if this is the most intuitive situation here... the above method will return null if it cant "DeHex" the string... byte[] decrypted = MachineKeyWrapper.EncryptOrDecryptData(false, encrypted, null, 0, encrypted.Length); @@ -34,8 +39,12 @@ public static HttpCookie Decrypt(HttpCookie cookie) HttpCookie decryptedCookie = CloneCookie(cookie); decryptedCookie.Value = System.Text.Encoding.Unicode.GetString(decrypted); - return decryptedCookie; +#else + HttpCookie decryptedCookie = CloneCookie(cookie); + decryptedCookie.Value = MachineKeyWrapper.Unprotect(cookie.Value); + return decryptedCookie; +#endif } catch(Exception ex) { @@ -65,14 +74,20 @@ public static HttpCookie Decrypt(HttpContext context, string cookieName) public static HttpCookie Encrypt(HttpCookie source) { try - { + { +#if NET10 || NET11 || NET20 || NET30 || NET35 byte[] data = System.Text.Encoding.Unicode.GetBytes(source.Value); byte[] encData = MachineKeyWrapper.EncryptOrDecryptData(true, data, null, 0, data.Length); HttpCookie encrypted = CloneCookie(source); encrypted.Value = MachineKeyWrapper.ByteArrayToHexString(encData, encData.Length); + return encrypted; +#else + HttpCookie encrypted = CloneCookie(source); + encrypted.Value = MachineKeyWrapper.Protect(source.Value); + return encrypted; +#endif - return encrypted; } catch(Exception ex) { diff --git a/src/HttpSecureCookie.Tests/HttpSecureCookie.Tests.csproj b/src/HttpSecureCookie.Tests/HttpSecureCookie.Tests.csproj index 379ec56..3c8fc3e 100644 --- a/src/HttpSecureCookie.Tests/HttpSecureCookie.Tests.csproj +++ b/src/HttpSecureCookie.Tests/HttpSecureCookie.Tests.csproj @@ -1,4 +1,4 @@ - + Debug @@ -10,7 +10,7 @@ Properties HttpSecureCookie.Tests HttpSecureCookie.Tests - v2.0 + v4.0 512 ..\ @@ -63,4 +63,4 @@ --> - \ No newline at end of file + diff --git a/src/HttpSecureCookie.csproj b/src/HttpSecureCookie.csproj index 0155ca0..1d7cd15 100644 --- a/src/HttpSecureCookie.csproj +++ b/src/HttpSecureCookie.csproj @@ -1,4 +1,4 @@ - + Local @@ -21,7 +21,7 @@ - v2.0 + v4.0 0.0 @@ -33,7 +33,7 @@ 285212672 false - TRACE;DEBUG;NET20 + TRACE;DEBUG;NET40 bin\Debug\HttpCookieEncryption.xml true 4096 @@ -95,4 +95,4 @@ - \ No newline at end of file + diff --git a/src/HttpSecureCookie.vs2010.sln b/src/HttpSecureCookie.vs2012.sln similarity index 96% rename from src/HttpSecureCookie.vs2010.sln rename to src/HttpSecureCookie.vs2012.sln index d59b717..6daedb2 100644 --- a/src/HttpSecureCookie.vs2010.sln +++ b/src/HttpSecureCookie.vs2012.sln @@ -1,14 +1,8 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Web", "Web", "{07C51070-88B8-42C5-A3BB-4FE803DB018D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebApplication20", "WebApplication20\WebApplication20.csproj", "{158FF55C-D492-476D-920D-FDDBC7D54F1C}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HttpSecureCookie", "HttpSecureCookie.csproj", "{094F2FA4-CF7B-4FCE-9532-C279C947BEDC}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HttpSecureCookie.Tests", "HttpSecureCookie.Tests\HttpSecureCookie.Tests.csproj", "{C27A039B-088D-4FD9-ABE0-8DE691400AAF}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{60FB8988-F293-4117-8EEC-12F9B8637AD9}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{E92BB1AA-6CBB-4EF9-AA9E-9022D945F007}" @@ -18,6 +12,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{E92BB1 .nuget\NuGet.targets = .nuget\NuGet.targets EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebApplication20", "WebApplication20\WebApplication20.csproj", "{158FF55C-D492-476D-920D-FDDBC7D54F1C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HttpSecureCookie", "HttpSecureCookie.csproj", "{094F2FA4-CF7B-4FCE-9532-C279C947BEDC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HttpSecureCookie.Tests", "HttpSecureCookie.Tests\HttpSecureCookie.Tests.csproj", "{C27A039B-088D-4FD9-ABE0-8DE691400AAF}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/src/MachineKey.cs b/src/MachineKey.cs index 40b31b4..cd8406c 100644 --- a/src/MachineKey.cs +++ b/src/MachineKey.cs @@ -1,3 +1,7 @@ +///Edited from original project at https://github.com/ericnewton76/httpsecurecookie +///Defined new build constants, NET20 || NET30 || NET35 +///30Mar16, Keyur Desai, Infosys + using System; using System.Reflection; @@ -11,7 +15,8 @@ public class MachineKeyWrapper private static MethodInfo _encOrDecData; static MachineKeyWrapper() - { + { +#if NET10 || NET11 || NET20 || NET30 || NET35 #if NET10 || NET11 //* this whole block hasnt been run tested yet. @@ -50,7 +55,8 @@ static MachineKeyWrapper() //Log.Error("Unable to get the methods to invoke: " + exMsg.TrimStart(',')); throw new InvalidOperationException("Unable to get the methods to invoke: " + exMsg.TrimStart(',')); } - } +#endif + } // for the record, I feel that this MachineKey class should be public. Why not have us // think about security only a little bit, and say, "Here... here's some nice helper @@ -62,7 +68,7 @@ static MachineKeyWrapper() /// /// string to convert /// byte array - public static byte[] HexStringToByteArray(string hex) + public static byte[] HexStringToByteArray(string hex) { int NumberChars = hex.Length / 2; byte[] bytes = new byte[NumberChars]; @@ -80,7 +86,7 @@ public static byte[] HexStringToByteArray(string hex) /// array to convert /// length of array to convert /// hex string representing the byte array. - public static string ByteArrayToHexString(byte[] p, int length) + public static string ByteArrayToHexString(byte[] p, int length) { char[] c = new char[p.Length * 2 + 2]; @@ -112,10 +118,48 @@ public static string ByteArrayToHexString(byte[] p, int length) /// beginning index /// length of array to operate on /// encrypted or decrypted byte array - public static byte[] EncryptOrDecryptData(bool encrypting, byte[] data, byte[] mod, int index, int length) + public static byte[] EncryptOrDecryptData(bool encrypting, byte[] data, byte[] mod, int index, int length) { return (byte[])_encOrDecData.Invoke(null, new object[] { encrypting, data, mod, index, length }); } + ///30Mar16 Addedd by Keyur Desai, Infosys, START + + /// + /// Uses .NET 4.0/4.5 API. + /// With MachineKeyProtection.Encryption option. + /// + /// String to be encrypted. + /// Encrypted string. + internal static string Protect(string input) + { + byte[] bytesToProtect = System.Text.Encoding.Unicode.GetBytes(input); +#if NET40 + return MachineKey.Encode(bytesToProtect, MachineKeyProtection.Encryption); +#else + byte[] protectedBytes = MachineKey.Protect(bytesToProtect); + return Convert.ToBase64String(protectedBytes); +#endif + } + + /// + /// Uses .NET 4.0/4.5 API. + /// With MachineKeyProtection.Encryption option. + /// + /// String to be decrypted. + /// Decrypted string. + internal static string Unprotect(string input) + { +#if NET40 + byte[] unprotectedBytes = MachineKey.Decode(input, MachineKeyProtection.Encryption); + return System.Text.Encoding.Unicode.GetString(unprotectedBytes); +#else + byte[] protectedBytes = Convert.FromBase64String(input); + byte[] unprotectedBytes = MachineKey.Unprotect(protectedBytes); + return System.Text.Encoding.Unicode.GetString(unprotectedBytes); +#endif + } + + ///30Mar16 Addedd by Keyur Desai, Infosys, END } } diff --git a/src/WebApplication20/WebApplication20.csproj b/src/WebApplication20/WebApplication20.csproj index fb5c78d..e543db6 100644 --- a/src/WebApplication20/WebApplication20.csproj +++ b/src/WebApplication20/WebApplication20.csproj @@ -1,5 +1,6 @@ - + + Debug AnyCPU @@ -12,9 +13,18 @@ Properties WebApplication20 WebApplication20 - v2.0 + v4.0 false + + + + + 4.0 + + + + true @@ -37,9 +47,15 @@ + + + + + + @@ -99,12 +115,17 @@ - {094F2FA4-CF7B-4FCE-9532-C279C947BEDC} + {094f2fa4-cf7b-4fce-9532-c279c947bedc} HttpSecureCookie + + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + - + + @@ -131,4 +152,4 @@ --> - \ No newline at end of file +