Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
10 changes: 6 additions & 4 deletions src/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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("")]

Expand All @@ -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")]
23 changes: 19 additions & 4 deletions src/HttpCookieEncryption.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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)
{
Expand Down Expand Up @@ -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)
{
Expand Down
6 changes: 3 additions & 3 deletions src/HttpSecureCookie.Tests/HttpSecureCookie.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
Expand All @@ -10,7 +10,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>HttpSecureCookie.Tests</RootNamespace>
<AssemblyName>HttpSecureCookie.Tests</AssemblyName>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
Expand Down Expand Up @@ -63,4 +63,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>
8 changes: 4 additions & 4 deletions src/HttpSecureCookie.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
<PropertyGroup>
<ProjectType>Local</ProjectType>
Expand All @@ -21,7 +21,7 @@
<StartupObject />
<FileUpgradeFlags>
</FileUpgradeFlags>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>0.0</OldToolsVersion>
Expand All @@ -33,7 +33,7 @@
<BaseAddress>285212672</BaseAddress>
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
<ConfigurationOverrideFile />
<DefineConstants>TRACE;DEBUG;NET20</DefineConstants>
<DefineConstants>TRACE;DEBUG;NET40</DefineConstants>
<DocumentationFile>bin\Debug\HttpCookieEncryption.xml</DocumentationFile>
<DebugSymbols>true</DebugSymbols>
<FileAlignment>4096</FileAlignment>
Expand Down Expand Up @@ -95,4 +95,4 @@
<PreBuildEvent />
<PostBuildEvent />
</PropertyGroup>
</Project>
</Project>
Original file line number Diff line number Diff line change
@@ -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}"
Expand All @@ -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
Expand Down
54 changes: 49 additions & 5 deletions src/MachineKey.cs
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -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.

Expand Down Expand Up @@ -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
Expand All @@ -62,7 +68,7 @@ static MachineKeyWrapper()
/// </summary>
/// <param name="str">string to convert</param>
/// <returns>byte array</returns>
public static byte[] HexStringToByteArray(string hex)
public static byte[] HexStringToByteArray(string hex)
{
int NumberChars = hex.Length / 2;
byte[] bytes = new byte[NumberChars];
Expand All @@ -80,7 +86,7 @@ public static byte[] HexStringToByteArray(string hex)
/// <param name="array">array to convert</param>
/// <param name="length">length of array to convert</param>
/// <returns>hex string representing the byte array.</returns>
public static string ByteArrayToHexString(byte[] p, int length)
public static string ByteArrayToHexString(byte[] p, int length)
{
char[] c = new char[p.Length * 2 + 2];

Expand Down Expand Up @@ -112,10 +118,48 @@ public static string ByteArrayToHexString(byte[] p, int length)
/// <param name="index">beginning index</param>
/// <param name="length">length of array to operate on</param>
/// <returns>encrypted or decrypted byte array</returns>
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

/// <summary>
/// Uses .NET 4.0/4.5 API.
/// With MachineKeyProtection.Encryption option.
/// </summary>
/// <param name="input">String to be encrypted.</param>
/// <returns>Encrypted string.</returns>
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
}

/// <summary>
/// Uses .NET 4.0/4.5 API.
/// With MachineKeyProtection.Encryption option.
/// </summary>
/// <param name="input">String to be decrypted.</param>
/// <returns>Decrypted string.</returns>
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
}
}
31 changes: 26 additions & 5 deletions src/WebApplication20/WebApplication20.csproj
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
Expand All @@ -12,9 +13,18 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>WebApplication20</RootNamespace>
<AssemblyName>WebApplication20</AssemblyName>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<UseIISExpress>false</UseIISExpress>
<TargetFrameworkProfile />
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>4.0</OldToolsVersion>
<IISExpressSSLPort />
<IISExpressAnonymousAuthentication />
<IISExpressWindowsAuthentication />
<IISExpressUseClassicPipelineMode />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
Expand All @@ -37,9 +47,15 @@
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Data" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Drawing" />
<Reference Include="System.Web" />
<Reference Include="System.Web.ApplicationServices" />
<Reference Include="System.Web.DynamicData" />
<Reference Include="System.Web.Entity" />
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
</ItemGroup>
<ItemGroup>
<Content Include="About.aspx" />
Expand Down Expand Up @@ -99,12 +115,17 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\HttpSecureCookie.csproj">
<Project>{094F2FA4-CF7B-4FCE-9532-C279C947BEDC}</Project>
<Project>{094f2fa4-cf7b-4fce-9532-c279c947bedc}</Project>
<Name>HttpSecureCookie</Name>
</ProjectReference>
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
Expand All @@ -131,4 +152,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>