Click here to Skip to main content
Click here to Skip to main content

HttpSecureCookie, A Way to Encrypt Cookies with ASP.NET 2.0

By , 3 Apr 2006
 

Introduction

I really have some good laughs when I tamper with cookies on my machine and watch the results when it is submitted back to the site. On the other hand, I don’t want any one to do the same to the cookies that I make!

Cookies, most of the times, shouldn’t be in plain text, at least, they should be tamper-proof! Revealing the content of your cookies might give curious and malicious people an idea about your application’s architecture, and that might help hacking it.

ASP.NET encodes and hashes its authorization ticket, making it secure and tamper-proof. However, the methods used to secure authorization cookies are inaccessible from outside the .NET framework libraries, so you can’t protect your own cookie using these methods; you need to protect it yourself using your own encryption key, encoding and hashing algorithms. HttpSecureCookie works around this by accessing the same methods ASP.NET uses for cookie authorization.

Of course, you shouldn’t save valuable information in your cookies, but if you have to, then this library is at your disposal.

Background

Before you start using this code, if you do not know what MachineKey is, I highly recommend checking this MSDN article: How To: Configure MachineKey in ASP.NET 2.0.

ASP.NET uses the System.Web.Security.CookieProtectionHelper internal class to decode and encode the content of a cookie before submitting it to the client. This class is based on the MachineKey. I wonder why Microsoft kept this class internal!?

To be able to access this internal class, I had to use reflection to be able to access the Decode and Encode methods of CookieProtectionHelper.

Eric Newton has a similar and good article on CP: Encrypting cookies to prevent tampering. However, that code is made for .NET 1.1 and it doesn't work with .NET 2.0 (but it does with some modifications); moreover, its resulting cipher text is in binary format versus being in encrypted format, and I don't know if this is a security risk. Also, I am accessing a higher level class System.Web.Security.CookieProtectionHelper than the one used by that article, System.Web.Configuration.MachineKey, to obtain the cryptography service, and that saved me time by not writing some low level code.

There is also another available method for encoding cookies, by using the FormsAuthenticationTicket and FormsAuthentication.Encrypt; for more information, check the section "Creating the Forms Authentication Cookie" on Explained: Forms Authentication in ASP.NET 2.0. However, I believe, the method mentioned in this article is more flexible.

Obtaining Reference to the CookieProtectionHelper Class via Reflection

To be able to access System.Web.Security.CookieProtectionHelper, I had to create a wrapper class CookieProtectionHelperWrapper which uses reflection to obtain a reference to the underlying methods and exposes the same methods as of the original class:

public static class CookieProtectionHelperWrapper {

    private static MethodInfo _encode;
    private static MethodInfo _decode;

    static CookieProtectionHelperWrapper() {
        // obtaining a reference to System.Web assembly
        Assembly systemWeb = typeof(HttpContext).Assembly;
        if (systemWeb == null) {
            throw new InvalidOperationException(
                "Unable to load System.Web.");
        }
        // obtaining a reference to the internal class CookieProtectionHelper
        Type cookieProtectionHelper = systemWeb.GetType(
                "System.Web.Security.CookieProtectionHelper");
        if (cookieProtectionHelper == null) {
            throw new InvalidOperationException(
                "Unable to get the internal class CookieProtectionHelper.");
        }
        // obtaining references to the methods of CookieProtectionHelper class
        _encode = cookieProtectionHelper.GetMethod(
                "Encode", BindingFlags.NonPublic | BindingFlags.Static);
        _decode = cookieProtectionHelper.GetMethod(
                "Decode", BindingFlags.NonPublic | BindingFlags.Static);

        if (_encode == null || _decode == null) {
            throw new InvalidOperationException(
                "Unable to get the methods to invoke.");
        }
    }

    public static string Encode(CookieProtection cookieProtection, 
                                byte[] buf, int count) {
        return (string)_encode.Invoke(null, 
                new object[] { cookieProtection, buf, count });
    }

    public static byte[] Decode(CookieProtection cookieProtection, 
                                string data) {
        return (byte[])_decode.Invoke(null, 
                new object[] { cookieProtection, data });
    }

}

MachineKeyCryptography: A Cryptography Class Based on MachineKey

MachineKeyCryptography is a static class that provides text ciphering and tamper-proofing services, it provides higher level access to CookieProtectionHelperWrapper. So, if you want to cipher any text based on the machine key, this class is the right one to use.

public static string Encode(string text, CookieProtection cookieProtection) {
    if (string.IsNullOrEmpty(text) || cookieProtection == CookieProtection.None) {
        return text;
    }
    byte[] buf = Encoding.UTF8.GetBytes(text);
    return CookieProtectionHelperWrapper.Encode(cookieProtection, buf, buf.Length); 
}

public static string Decode(string text, CookieProtection cookieProtection) {
    if (string.IsNullOrEmpty(text)) {
        return text;
    }
    byte[] buf;
    try {
        buf = CookieProtectionHelperWrapper.Decode(cookieProtection, text);
    }
    catch(Exception ex) {
        throw new InvalidCypherTextException(
            "Unable to decode the text", ex.InnerException);
    }
    if (buf == null || buf.Length == 0) {
        throw new InvalidCypherTextException(
            "Unable to decode the text");
    }
    return Encoding.UTF8.GetString(buf, 0, buf.Length);
}

HttpSecureCookie Class

This static class will handle the service of securing the content of a cookie. Also, it provides a service to clone a cookie. This class uses MachineKeyCryptography internally to provide crypting services:

public static class HttpSecureCookie {

    public static HttpCookie Encode(HttpCookie cookie) {
        return Encode(cookie, CookieProtection.All);
    }

    public static HttpCookie Encode(HttpCookie cookie, 
                  CookieProtection cookieProtection) {
        HttpCookie encodedCookie = CloneCookie(cookie);
        encodedCookie.Value = 
          MachineKeyCryptography.Encode(cookie.Value, cookieProtection);
        return encodedCookie;
    }

    public static HttpCookie Decode(HttpCookie cookie) {
        return Decode(cookie, CookieProtection.All);
    }

    public static HttpCookie Decode(HttpCookie cookie, 
                  CookieProtection cookieProtection) {
        HttpCookie decodedCookie = CloneCookie(cookie);
        decodedCookie.Value = 
          MachineKeyCryptography.Decode(cookie.Value, cookieProtection);
        return decodedCookie;
    }

    public static HttpCookie CloneCookie(HttpCookie cookie) {
        HttpCookie clonedCookie = new HttpCookie(cookie.Name, cookie.Value);
        clonedCookie.Domain = cookie.Domain;
        clonedCookie.Expires = cookie.Expires;
        clonedCookie.HttpOnly = cookie.HttpOnly;
        clonedCookie.Path = cookie.Path;
        clonedCookie.Secure = cookie.Secure;

        return clonedCookie;
    }
}

Using the Code

Using HttpSecureCookie is easy; for a complete demo, please check the sample application. To encode a cookie:

HttpCookie cookie = new HttpCookie("UserName", "Terminator");
cookie.Expires = DateTime.Now.AddDays(1);
HttpCookie encodedCookie = HttpSecureCookie.Encode(cookie);
Response.Cookies.Add(encodedCookie);

To decode an encoded cookie:

HttpCookie cookie = Request.Cookies["UserName"];
lblDisplayBefore.Text = cookie.Value;
HttpCookie decodedCookie = HttpSecureCookie.Decode(cookie);

To use HttpSecureCookie on a web farm, you need to set the correct MachineKey configuration in Web.Config. For more information, check the "Web Farm Deployment Considerations" section on How To: Configure MachineKey in ASP.NET 2.0. To generate a machine key, please check How to create keys by using Visual C# .NET for use in Forms authentication.

Limitations

This library uses reflection, so it might break with the next version of .NET. Also, it doesn't work with .NET 1.1.

Reflection might have some performance implication; however, I used an assembly that is already loaded, "System.Web.dll", and I am only using reflection once across the life time of the application, to gain extra performance.

Conclusion

If you don't want a sophisticated cookie encryption service, if you don't want to mind the encryption key, and if you don't want to create your own encryption algorithm, then this library is for you!

Comments and suggestions are welcome. Please vote if you like this article (or if you didn't).

History

  • 1 April 2006 - First version.

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)

About the Author

Adam Tibi
Team Leader
United Kingdom United Kingdom
Member
Software Consultant, Lives in Guildford/Surrey, UK.
 
www.AdamTibi.net

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionBug on 4.5 framework ?memberdiego mesa tabares5 Oct '12 - 6:29 
On 4.0 framework HttpSecureCookie was working fine, but I updated my app to 4.5 and I got:
 
System.ArgumentException: Object type 'System.Int32' cannot be converted to the type 'System.Web.Security.Cryptography.Purpose'. en System.RuntimeType.TryChangeType(Object value, Binder binder, CultureInfo culture, Boolean needsSpecialCast) in System.RuntimeType.CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr) en System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig) in System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) in System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) in AdamTibi.Web.Security.CookieProtectionHelperWrapper.Encode(CookieProtection cookieProtection, Byte[] buf, Int32 count) en AdamTibi.Web.Security.MachineKeyCryptography.Encode(String text, CookieProtection cookieProtection) en AdamTibi.Web.Security.HttpSecureCookie.Encode(HttpCookie cookie, CookieProtection cookieProtection) in AdamTibi.Web.Security.HttpSecureCookie.Encode(HttpCookie cookie)
 
I hope you could test it. Thank you
AnswerRe: Bug on 4.5 framework ?memberAdam Tibi5 Oct '12 - 16:19 
Later versions of ASP.NET has added the functionality provided by this article, so, if you are on 4.5, you should be using methods from the framework.
Make it simple, as simple as possible, but not simpler.

SuggestionInternal class and reflectionmembervasekz11 Feb '12 - 7:33 
For new implementations of this examples I suggest using System.Web.Security.MachineKey class instead of internal CookieProtectionHelper and reflection.
 
private static string Encode(string text)
{
	if (string.IsNullOrEmpty(text))
		return text;
	byte[] buf = Encoding.UTF8.GetBytes(text);
	return System.Web.Security.MachineKey.Encode(buf, MachineKeyProtection.All);
}
 
private static string Decode(string text)
{
	if (string.IsNullOrEmpty(text))
		return text;
	byte[] buf = System.Web.Security.MachineKey.Decode(text, MachineKeyProtection.All);
	return Encoding.UTF8.GetString(buf);
}
 
Works like a charm.
GeneralRe: Internal class and reflectionmemberAdam Tibi13 Feb '12 - 10:41 
Hi Vasekz
 
In .NET 2.0 this API did not exist (this is when the article was written).
Make it simple, as simple as possible, but not simpler.

GeneralRe: Internal class and reflectionmemberJasonJoh3 Aug '12 - 0:44 
Oh, it's very safe and simple.
But this class is asp.net v.4.0, ys there any equivalence with 3.5?
GeneralNot update cookie instantlymemberashutosh kumar jha20 May '11 - 0:15 
Dear Sir,
 
I used your Dll file in my code but i m facing Problem.
 
like I have a page where i put 2 Buttons "Add", "Display".
 
if i call encode and decode both function on "Add" button then its showing last value.
 
but if i click one by one like firstly "Add" then "Display" then its showing Correct Result.
 
for Ex:=
****************************
string sShoppingCartCookieName = "ashutestcookie";
 
protected void Add_Click(object sender, EventArgs e)
{
AddToShoppingCart(1, 1, 1, "voucher");
HttpCookie oCookie = (HttpCookie)HttpContext.Current.Request.Cookies[sShoppingCartCookieName];
HttpCookie decodedCookie = HttpSecureCookie.Decode(oCookie);
string sProductID = decodedCookie.Values["quantity"].ToString();
Response.Write(sProductID);
}
**********************************
protected void Display_Click(object sender, EventArgs e)
{
HttpCookie oCookie = (HttpCookie)HttpContext.Current.Request.Cookies[sShoppingCartCookieName];
HttpCookie decodedCookie = HttpSecureCookie.Decode(oCookie);
string sProductID = decodedCookie.Values["quantity"].ToString();
Response.Write(sProductID);
}
**************************
 
public void AddToShoppingCart(int item_ID, int quantity, int cid, string vouchervalue)
{
 
if (HttpContext.Current.Request.Cookies[sShoppingCartCookieName] == null)
{
HttpCookie oCookie = new HttpCookie(sShoppingCartCookieName);
//Set Cookie to expire in 3 hours
oCookie.Expires = DateTime.Now.AddHours(1);
oCookie.Values["item_ID"] = item_ID.ToString();
oCookie.Values["quantity"] = quantity.ToString();
oCookie.Values["cid"] = cid.ToString();
oCookie.Values["vouchervalue"] = vouchervalue;//new added on 250510
// oCookie.Domain = sShoppingCartCookie_DomainName;
oCookie.HttpOnly = true;
HttpCookie encodedCookie = HttpSecureCookie.Encode(oCookie);
HttpContext.Current.Response.Cookies.Add(encodedCookie);
}
else
{
bool bExists = false;
char[] sep = { ',' };
HttpCookie decodedCookie = (HttpCookie)HttpContext.Current.Request.Cookies[sShoppingCartCookieName];
HttpCookie oCookie = HttpSecureCookie.Decode(decodedCookie);
oCookie.Expires = DateTime.Now.AddHours(1);
 
//Check if Cookie already contain same item
string sProdID = oCookie.Values["item_ID"].ToString();
string sQuantity = oCookie.Values["quantity"].ToString();
string scid = oCookie.Values["cid"].ToString();
string svouchervalue = oCookie.Values["vouchervalue"].ToString();//new added on 250510
string[] arrCookie = sProdID.Split(sep);
string[] arrQuantityCookie = sQuantity.Split(sep);
string[] arrCidCookie = scid.Split(sep);
string[] arrVouchervalueCookie = svouchervalue.Split(sep);//new added on 250510
for (int i = 0; i < arrCookie.Length; i++)
{
if (arrCookie[i].Trim() == item_ID.ToString().Trim() && arrCidCookie[i].Trim() == cid.ToString())
{
bExists = true;
if (arrVouchervalueCookie[i] != "P")// "P" denoted promotion)
{
//Update Quantity
this.UpdateShoppingCart(item_ID, quantity, cid);
}
}
}
if (!bExists)
{
if (oCookie.Values["item_ID"].Length == 0)
{
oCookie.Values["item_ID"] = item_ID.ToString();
oCookie.Values["quantity"] = quantity.ToString();
oCookie.Values["cid"] = cid.ToString();
oCookie.Values["vouchervalue"] = vouchervalue.ToString();//new added on 250510
}
else
{
oCookie.Values["item_ID"] = oCookie.Values["item_ID"] + "," + item_ID;
oCookie.Values["quantity"] = oCookie.Values["quantity"] + "," + quantity;
oCookie.Values["cid"] = oCookie.Values["cid"] + "," + cid;
oCookie.Values["vouchervalue"] = oCookie.Values["vouchervalue"] + "," + vouchervalue;//new added on 250510
}
// oCookie.Domain = sShoppingCartCookie_DomainName;
oCookie.HttpOnly = true;
oCookie.Secure = true;
HttpCookie encodedCookie = HttpSecureCookie.Encode(oCookie);
HttpContext.Current.Response.Cookies.Add(encodedCookie);
}
 
}
 
}
 

*******************************
public void UpdateShoppingCart(int item_ID, int quantity, int cid)
{
if (HttpContext.Current.Request.Cookies[sShoppingCartCookieName] == null)
{
//Do nothing
}
else
{
char[] sep = { ',' };
//HttpCookie oCookie = (HttpCookie)HttpContext.Current.Request.Cookies[sShoppingCartCookieName];
////Set Cookie to expire in 3 hours
//oCookie.Expires = DateTime.Now.AddHours(Global.dShoppingCartCookieExpires);
HttpCookie decodedCookie = (HttpCookie)HttpContext.Current.Request.Cookies[sShoppingCartCookieName];
//Set Cookie to expire in 3 hours
decodedCookie.Expires = DateTime.Now.AddHours(1);
HttpCookie oCookie = HttpSecureCookie.Decode(decodedCookie);
//Check if Cookie already contain same item
string sProdID = oCookie.Values["item_ID"].ToString();
string squantity = oCookie.Values["quantity"].ToString();
string scid = oCookie.Values["cid"].ToString();
string svouchervalue = oCookie.Values["vouchervalue"].ToString();//new added on 250510
 
string[] arrCookie = sProdID.Split(sep);
string[] arrCookie1 = squantity.Split(sep);
string[] arrCookie4 = scid.Split(sep);
string[] arrCookie6 = svouchervalue.Split(sep);//new added on 250510
 
string[] arrCookie2 = new string[arrCookie.Length];
string[] arrCookie3 = new string[arrCookie1.Length];
string[] arrCookie5 = new string[arrCookie4.Length];
string[] arrCookie7 = new string[arrCookie6.Length];//new added on 250510
 
int j = 0;
for (int i = 0; i < arrCookie.Length; i++)
{
if (arrCookie[i].Trim() == item_ID.ToString() && arrCookie4[i].Trim() == cid.ToString())
{
arrCookie2[j] = arrCookie[i];
arrCookie5[j] = arrCookie4[i];
arrCookie7[j] = arrCookie6[i];//new added on 250510
int quan = Convert.ToInt32(arrCookie1[i].ToString());
quan = quan + quantity;
arrCookie3[j] = quan.ToString();
j++;
}
else
{
arrCookie2[j] = arrCookie[i];
arrCookie3[j] = arrCookie1[i];
arrCookie5[j] = arrCookie4[i];
arrCookie7[j] = arrCookie6[i];//new added on 250510
j++;
}
 
}
string sCookieID = "";
string sCookieID2 = "";
string sCookieID3 = "";
string sCookieID4 = "";//new added on 250510
for (int i = 0; i < arrCookie2.Length; i++)
{
sCookieID = sCookieID + arrCookie2[i] + ",";
sCookieID2 = sCookieID2 + arrCookie3[i] + ",";
sCookieID3 = sCookieID3 + arrCookie5[i] + ",";
sCookieID4 = sCookieID4 + arrCookie7[i] + ",";//new added on 250510
}
if (sCookieID.Length > 0)
{
oCookie.Values["item_ID"] = sCookieID.Substring(0, sCookieID.Length - 1);
oCookie.Values["quantity"] = sCookieID2.Substring(0, sCookieID2.Length - 1);
oCookie.Values["cid"] = sCookieID3.Substring(0, sCookieID3.Length - 1);
oCookie.Values["vouchervalue"] = sCookieID4.Substring(0, sCookieID4.Length - 1);//new added on 250510
}
else
{
oCookie.Values["item_ID"] = "";
oCookie.Values["quantity"] = "";
oCookie.Values["cid"] = "";
oCookie.Values["vouchervalue"] = "";
}
// oCookie.Domain = Global.sShoppingCartCookie_DomainName;
oCookie.HttpOnly = true;
// HttpContext.Current.Response.Cookies.Add(oCookie);
 

 

//HttpCookie encodedCookie = HttpSecureCookie.Encode(oCookie);
//HttpContext.Current.Response.Cookies.Add(encodedCookie);
HttpCookie encodedCookie = new HttpCookie(sShoppingCartCookieName);
encodedCookie = HttpSecureCookie.Encode(oCookie);
if (Request.Cookies[sShoppingCartCookieName] != null)
{
HttpContext.Current.Response.Cookies.Add(encodedCookie);
}
 

}
}
 
***********************
ashutosh kumar jha

GeneralNot working reliably in a web farm, even though machineKeys are syncedmemberfrankosaurus3 Dec '10 - 16:03 
I am using this to encrypt and decrypt cookies in my website.
 
I have found that certain web servers in the farm cannot decrypt cookies created by others.
 
However, I took special care to sync up the values of machineKey validationKey and machineKey decryptionKey across all nodes in the web farm.
 
What is the problem? Is there some other config value that needs to be synced across the servers?
 
I am running IIS7 and .NET 3.5 SP1.
GeneralRe: Not working reliably in a web farm, even though machineKeys are syncedmemberfrankosaurus5 Dec '10 - 14:10 
Found the issue. The security patches were out of sync on the servers.
The following patch appears to affect the way this algorithm works:
 
http://www.microsoft.com/technet/security/bulletin/ms10-070.mspx
GeneralWas working great - now throwing errorsmemberChuck Bevitt4 Nov '10 - 13:42 
I've used this for a couple of years on my web apps; it's been working great. Suddenly, a month or so ago, it started occasionally throwing errors. This only happens 5 to 15 times a day, on a site with thousands of hits per day.
 
Before anyone asks, yes, the web site is on a server farm and I do specify the machine key in the web config file. I haven't made any changes that could account for this.
 
Here are a couple of the errors from our error notification emails, which unwind the inner exceptions:
 
Error Ticket is: VSIIS1_11-04-2010___3
 
Message(0): /Login.aspx, IP: 209.99.19.8, Raw User Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
 
Stack Trace(0):
 
Source(0): Error.aspx
 
Message(1): Exception of type 'System.Web.HttpUnhandledException' was thrown.
 
Stack Trace(1): at System.Web.UI.Page.HandleError(Exception e)
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
at System.Web.UI.Page.ProcessRequest()
at System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext context)
at System.Web.UI.Page.ProcessRequest(HttpContext context)
at ASP.login_aspx.ProcessRequest(HttpContext context)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
 
Source(1): System.Web
 
Message(2): Unable to decode the text
 
Stack Trace(2): at AdamTibi.Web.Security.MachineKeyCryptography.Decode(String text, CookieProtection cookieProtection)
at AdamTibi.Web.Security.HttpSecureCookie.Decode(HttpCookie cookie, CookieProtection cookieProtection)
at AdamTibi.Web.Security.HttpSecureCookie.Decode(HttpCookie cookie)
at Global.get_AccessAccountID()
at Global.SetPreferenceCookies()
at _Default.Authenticate(String cUser, String cPass, String& cFailureText)
at _Default.Login1_Authenticate(Object sender, AuthenticateEventArgs e)
at System.Web.UI.WebControls.Login.OnAuthenticate(AuthenticateEventArgs e)
at System.Web.UI.WebControls.Login.AttemptLogin()
at System.Web.UI.WebControls.Login.OnBubbleEvent(Object source, EventArgs e)
at System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args)
at System.Web.UI.WebControls.Button.OnCommand(CommandEventArgs e)
at System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument)
at System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument)
at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
at System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
 
Source(2): AdamTibi.Web.Security
 
Message(3): Unable to validate data.
 
Stack Trace(3): at System.Web.Configuration.MachineKeySection.EncryptOrDecryptData(Boolean fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length, IVType ivType, Boolean useValidationSymAlgo, Boolean signData)
at System.Web.Configuration.MachineKeySection.EncryptOrDecryptData(Boolean fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length, IVType ivType, Boolean useValidationSymAlgo)
at System.Web.Security.CookieProtectionHelper.Decode(CookieProtection cookieProtection, String data)
 
Source(3): System.Web
 

 
Error Ticket is: VSIIS2_11-04-2010___2
 
Message(0): /Login.aspx, IP: 206.216.34.171, Raw User Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648)
 
Stack Trace(0):
 
Source(0): Error.aspx
 
Message(1): Exception of type 'System.Web.HttpUnhandledException' was thrown.
 
Stack Trace(1): at System.Web.UI.Page.HandleError(Exception e)
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
at System.Web.UI.Page.ProcessRequest()
at System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext context)
at System.Web.UI.Page.ProcessRequest(HttpContext context)
at ASP.login_aspx.ProcessRequest(HttpContext context)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
 
Source(1): System.Web
 
Message(2): Unable to decode the text
 
Stack Trace(2): at AdamTibi.Web.Security.MachineKeyCryptography.Decode(String text, CookieProtection cookieProtection)
at AdamTibi.Web.Security.HttpSecureCookie.Decode(HttpCookie cookie, CookieProtection cookieProtection)
at AdamTibi.Web.Security.HttpSecureCookie.Decode(HttpCookie cookie)
at Global.get_AccessAccountID()
at Global.SetPreferenceCookies()
at _Default.Authenticate(String cUser, String cPass, String& cFailureText)
at _Default.Login1_Authenticate(Object sender, AuthenticateEventArgs e)
at System.Web.UI.WebControls.Login.OnAuthenticate(AuthenticateEventArgs e)
at System.Web.UI.WebControls.Login.AttemptLogin()
at System.Web.UI.WebControls.Login.OnBubbleEvent(Object source, EventArgs e)
at System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args)
at System.Web.UI.WebControls.Button.OnCommand(CommandEventArgs e)
at System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument)
at System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument)
at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
at System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
 
Source(2): AdamTibi.Web.Security
 
Message(3): Length of the data to decrypt is invalid.
 
Stack Trace(3): at System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
at System.Security.Cryptography.CryptoStream.FlushFinalBlock()
at System.Web.Configuration.MachineKeySection.EncryptOrDecryptData(Boolean fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length, IVType ivType, Boolean useValidationSymAlgo)
at System.Web.Security.CookieProtectionHelper.Decode(CookieProtection cookieProtection, String data)
 
Source(3): mscorlib
 

I thought at first that we were starting to get hits from mobile devices that were causing the problem; adding the raw user agent to the error notification proved that that is not the case.
 
My best guess is that some Microsoft patch may have caused the problem.
 
It's running on IIS6 on Windows Server 2003 (virtual machines) and ASP.Net 2.0.
 
If anyone has any ideas, I'd really appreciate it. Remember, the problem only occurs a few times each day - usually it works fine.
 
Anyway, thanks for the library - it's worked great up to now.
GeneralRe: Was working great - now throwing errorsmembermoabi K15 May '11 - 17:55 
Hi Chuck we are also getting the same problem and we guess its a Microsoft patch. Better still how did you solve this problem? Its still a good library.
GeneralRe: Was working great - now throwing errorsmemberChuck Bevitt16 May '11 - 6:18 
I actually didn't solve the problem. The place where I was using encryption wasn't really critical, so I just whipped up a custom class to substitute for this one using a simple substitution cipher that I could get in place quickly. Later if I need to I might go back and rewrite the custom class to replace the simple cipher with something using the .Net encryption classes.
GeneralRe: Was working great - now throwing errorsmemberdiego mesa tabares29 Sep '11 - 11:58 
Hello I was able to solve the problem setting a machine key in my application web.config, in the system.web section, I generated the key using this tool:
 

http://aspnetresources.com/tools/machineKey

 
Hope this helps Smile | :)
GeneralI'm pretty sure I'm missing something, but...memberreinux1 Nov '10 - 21:26 
What's the difference between using this and using System.Web.Security.MachineKey.Encrypt() ?
GeneralRe: I'm pretty sure I'm missing something, but...memberfrankosaurus5 Dec '10 - 14:06 
It seems that class is only available in .NET Framework version 4. This article was targeting .NET Framework 2.0.
GeneralRe: I'm pretty sure I'm missing something, but...memberreinux5 Dec '10 - 14:46 
Ah right... stupid me x_x
GeneralThanks for the propsmemberericnewton769 Jul '10 - 7:12 
Thanks for the props in your article.
 
Big Grin | :-D
GeneralMedium TrustmemberSpiff Dog1 Mar '10 - 10:40 
Since this uses Reflection, I gather that this will not run in a default Medium Trust environment at a hosting provider. Any idea how to do this so it will work?
 
Perhaps you could implement one of the Crypto providers in the System.Security.Cryptography namespace?
-------------------------
Spiffdog Design
It's ok... he doesn't bite...

GeneralRe: Medium TrustmemberAdam Tibi2 Mar '10 - 0:12 
Hi
 
I never tried this in a medium trus enviroment.
 
You could always refer to your own encryption strategy
Make it simple, as simple as possible, but not simpler.

GeneralThanks for the insight Adam...I've actually implemented your code in my projectmemberZiad J.khan26 Nov '09 - 10:45 
Session, Cookie, Query String & Cache Variables Unified
 
Regards
Ziad
GeneralRe: Thanks for the insight Adam...I've actually implemented your code in my projectmemberAdam Tibi30 Nov '09 - 2:20 
Thank you Ziad Smile | :)
 
Make it simple, as simple as possible, but not simpler.

Generalerror : padding is invalid...memberjamel197416 Sep '08 - 4:39 
hi adam,
i've a login page with a checkbox if i want to remember password. If this checkbox is checked, i encode the password in the cookies .
I've a problem when i compile in debug with visual it's OK but if i launch direct my site (http://localhost/mysite) i've the following error message:Padding is invalid and cannot be removed
if i delete my cookies and i try again it's ok but if i launch again with visual (without delete the cookies) in debug i've the same error
 
source:mscorlib
 
Line 58:                  catch(Exception ex) {
Line 59:                        throw new InvalidCypherTextException("Unable to decode the text", ex.InnerException);
Line 60:                  }
Line 61:                  if (buf == null || buf.Length == 0) {
 
Source File: C:\MJL\MySite\Sources\MySite_ClassLibrary\Security\MachineKeyCryptography.cs      Line: 59
Stack trace
[CryptographicException: Padding is invalid and cannot be removed.]
   System.Security.Cryptography.RijndaelManagedTransform.DecryptData(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount, Byte[]&amp; outputBuffer, Int32 outputOffset, PaddingMode paddingMode, Boolean fLast) +1490188
   System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount) +306
   System.Security.Cryptography.CryptoStream.FlushFinalBlock() +30
   System.Web.Configuration.MachineKeySection.EncryptOrDecryptData(Boolean fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length, Boolean useValidationSymAlgo) +154
   System.Web.Security.CookieProtectionHelper.Decode(CookieProtection cookieProtection, String data) +79
 
[InvalidCypherTextException: Unable to decode the text]
 
have you an idea?
thanks
GeneralRe: error : padding is invalid...memberAdam Tibi16 Sep '08 - 11:54 
Hi,
 
Recheck if you have set a machine key in your web.config which also should be the same across your web servers. Also, do you have any security software being active? Did you try different browserw?
 
Another question for you, why don't you use the membership provider which is introduced with ASP.NET 2. It is flexible and the save password feature is a "built-in".
 
Regards
 
Make it simple, as simple as possible, but not simpler.
Looking to hire .NET Software Consultant in UK?

GeneralRe: error : padding is invalid...memberjamel197416 Sep '08 - 21:03 
i use the membership provider but i must have add 2 textbox because i use the username to load informations in the session (in the code c#) otherwise (without my textbox but with textbox of asp:login), i don't have recover the login: asp: <asp:Login ID="UserLoginCtrl"...
c#: UserLoginCtrl.UserName is always empty.(I surely do something wrong). I'd like to use the component more simply but i can not...
Regarding my first problem i ve tried with firefox and i ve no problem...
GeneralRe: error : padding is invalid...memberjamel197416 Sep '08 - 22:21 
the 2 textboxes are in component it's just a breaking down into <template> but without this breaking down, i don't recover my data. in this case the gestion is not hidden and i must do manually (gestion of cookies). I hope that it's clear enough
thanks
GeneralInvalidCypherText.... no good.memberKurtPW29 Aug '08 - 13:31 
Adam:
 
I get a CS0246: The type or namespace name 'InvalidCypherTextException' could not be found (are you missing a using directive or an assembly reference?)
 
... error at: throw new InvalidCypherTextException("Unable to decode the text", ex.InnerException);
 
I cannot find this exception in any of the .Net docs. The closest I come up with is a InvalidCipherTextException() in BouncyCastle. Where in .Net is this exception defined? I'm not sure what namespace in use.
 
Thanks
 
Kurt

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130523.1 | Last Updated 3 Apr 2006
Article Copyright 2006 by Adam Tibi
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid