using System;
using System.IO;
using System.Xml;
using System.Web;
using System.Text;
using System.Collections.Specialized;
using System.Security.Cryptography;
namespace BulletProofCookiesArticle
{
/// <summary>
/// Summary description for CHelperMethods.
/// </summary>
public class CHelperMethods
{
// you should properly create your own keys and ivs
private static byte[] key_192 = new byte[]
{10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10};
private static byte[] iv_128= new byte[]
{10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 10};
public static string EncryptRijndaelManaged(string value)
{
if (value == "")
return "";
RijndaelManaged crypto = new RijndaelManaged();
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, crypto.CreateEncryptor(key_192, iv_128),
CryptoStreamMode.Write);
StreamWriter sw = new StreamWriter(cs);
sw.Write(value);
sw.Flush();
cs.FlushFinalBlock();
ms.Flush();
return Convert.ToBase64String(ms.GetBuffer(), 0, (int) ms.Length);
}
public static string DecryptRijndaelManaged(string value)
{
if (value == "")
return "";
RijndaelManaged crypto = new RijndaelManaged();
MemoryStream ms = new MemoryStream(Convert.FromBase64String(value));
CryptoStream cs = new CryptoStream(ms, crypto.CreateDecryptor(key_192, iv_128),
CryptoStreamMode.Read);
StreamReader sw = new StreamReader(cs);
return sw.ReadToEnd();
}
public static string SignAndSecureData(string value)
{
return SignAndSecureData(new string[] {value});
}
public static string SignAndSecureData(string[] values)
{
throw new Exception("Please set your own XML RSA Key before you can run this sample");
string xmlKey = "";
return SignAndSecureData(xmlKey, values);
}
public static string SignAndSecureData(string xmlKey, string[] values)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml("<x></x>");
for (int i = 0; i < values.Length; i++)
_AddNode(xmlDoc, "v" + i.ToString(), values[i]);
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(xmlKey);
byte[] signature = rsa.SignData(Encoding.ASCII.GetBytes(xmlDoc.InnerXml),
"SHA1");
_AddNode(xmlDoc, "s", Convert.ToBase64String(signature, 0, signature.Length));
return EncryptRijndaelManaged(xmlDoc.InnerXml);
}
public static bool DecryptAndVerifyData(string input, out string[] values)
{
throw new Exception("Please set your own XML RSA Key before you can run this sample");
string xmlKey = "";
return DecryptAndVerifyData(xmlKey, input, out values);
}
public static bool DecryptAndVerifyData(string xmlKey, string input, out string[] values)
{
string xml = DecryptRijndaelManaged(input);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml);
values = null;
XmlNode node = xmlDoc.GetElementsByTagName("s")[0];
node.ParentNode.RemoveChild(node);
// verify
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(xmlKey);
byte[] signature = Convert.FromBase64String(node.InnerText);
byte[] data = Encoding.ASCII.GetBytes(xmlDoc.InnerXml);
if (!rsa.VerifyData(data, "SHA1", signature))
return false;
// count values
int count;
for (count = 0; count < 100; count++)
{
if (xmlDoc.GetElementsByTagName("v" + count.ToString())[0] == null)
break;
}
values = new string[count];
for (int i = 0; i < count; i++)
values[i] = xmlDoc.GetElementsByTagName("v" + i.ToString())[0].InnerText;
return true;
}
public static void SignAndSecureCookie(HttpCookie cookie, NameValueCollection serverVariables)
{
if (cookie.HasKeys)
throw (new Exception("Does not support cookies with sub keys"));
if (cookie.Expires != DateTime.MinValue) // has an expiry date
{
cookie.Value = SignAndSecureData(new string[]
{
cookie.Value,
serverVariables["REMOTE_ADDR"],
cookie.Expires.ToString()});
}
else
{
cookie.Value = SignAndSecureData(new string[]
{cookie.Value, serverVariables["REMOTE_ADDR"]});
}
}
public static string DecryptAndVerifyCookie(HttpCookie cookie, NameValueCollection serverVariables)
{
if (cookie == null)
return null;
string[] values;
if (!DecryptAndVerifyData(cookie.Value, out values))
return null;
if (values.Length == 3) // 3 values, has an expiry date
{
DateTime expireDate = DateTime.Parse(values[2]);
if (expireDate < DateTime.Now)
return null;
}
if (values[1] != serverVariables["REMOTE_ADDR"])
return null;
return values[0];
}
private static void _AddNode(XmlDocument xmlDoc, string name, string content)
{
XmlElement elem = xmlDoc.CreateElement(name);
XmlText text = xmlDoc.CreateTextNode(content);
xmlDoc.DocumentElement.AppendChild(elem);
xmlDoc.DocumentElement.LastChild.AppendChild(text);
}
}
}