Decrypting data that was encrypted with FormsAuthentication.Encrypt - asp.net

I am encrypting data into a cookie via FormsAuthentication.Encrypt(data) in a .Net 4.0 ASP.Net web application deployed on a development web farm. I have specified a machineKey attribute to hard-code the ValidationKey, DecryptionKey, and Decryption (algorithm).
Now, I am trying to decrypt that cookie using an application i built on my development workstation. I am able to get the cookie via Request.Cookies["CookieName"] but when I attempt to decrypt the value via FormsAuthentication.Decrypt(encCookie), I get the following error:
Unable to validate data. at
System.Web.Configuration.MachineKeySection.EncryptOrDecryptData(Boolean
fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length,
Boolean useValidationSymAlgo, Boolean useLegacyMode, IVType ivType,
Boolean signData) at
System.Web.Security.FormsAuthentication.Decrypt(String
encryptedTicket) at TuoVanitySite.Default.Page_Load(Object sender,
EventArgs e) in
c:\src\ets_2008\main\ebtDev\Sandboxes\rrozinov\TuoVanitySite\TuoVanitySite\Default.aspx.cs:line
22
Here is blurp from my web config (keys were removed):
<machineKey
validationKey="keyA"
decryptionKey="keyB"
decryption="3DES"
compatibilityMode="Framework20SP1"/>
Anyone has dealt with this situation where machineKey was not enough?

Ok, I was able to find a solution for my problem however i am not sure why this works.
I had to add the validation attribute to the machineKey:
<machineKey
validationKey="keyA"
decryptionKey="keyB"
validation="SHA1"
decryption="3DES"
compatibilityMode="Framework20SP1"/>
What makes it a bit interesting is the fact that regardless whether i put SHA1 or 3DES, my code can decrypt just fine. I did confirm that server is using default SHA1. I am still open to find a root cause for educational purposes.

as is mentioned in the "How To: Configure MachineKey in ASP.NET 2.0" article :
HMACSHA1 is used even if validation is set to AES or 3DES
So it may be the case that if the compatibility mode is set to Framework20SP1 or Framework20SP2 then it uses SHA1 regardless of what is set in the validation attribute.
I'm struggling with similar task at the moment - setting up single sign on between ASP.Net 4.0 and 3.5SP1 web applications that are deployed on IIS8 on Windows Server 2012. It gets more complicated because Win2k12 has .Net 4.5.1 which is an "in-place" upgrade to 4.0...

Related

ViewState Encryption doesn't work with mixed algorithms

I have a client who wants to turn on ViewState encryption in an ASP.NET Web Forms application. They are not able to use the default algorithms because of FIPS compliance. The initial request from the client was to use 3DES/AES as follows, which I added to the web.config file:
<machineKey validationKey="..." decryptionKey="..." validation="3DES" decryption="AES" />
Putting in this configuration caused the application to stop working with the following error:
[HttpException (0x80004005): Unable to validate data.]
System.Web.Configuration.MachineKeySection.EncryptOrDecryptData(Boolean fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length, Boolean useValidationSymAlgo, Boolean useLegacyMode, IVType ivType, Boolean signData) +1090
System.Web.UI.Page.EncryptString(String s, Purpose purpose) +150
[...]
By switching both keys to 3DES, I was able to get the system working.
Why does the system fail when the two different algorithms are used?
Not quite sure why that's failing - perhaps some error with the length of the key provided? The inner exception should be able to tell you more if there's one present.
Regardless, you should be aware that 3DES is being phased out by NIST and that ASP.NET does not use 3DES in a FIPS-compliant fashion. (Reference: http://csrc.nist.gov/publications/nistpubs/800-67-Rev1/SP-800-67-Rev1.pdf. See in particular the foreword, which states that we're in a transitional period for customers to move off of 3DES and on to AES. Also see Section 3.5; ASP.NET does not limit the number of invocations of the block cipher algorithm, so our particular usage of this algorithm makes it non-FIPS-compliant.)
The best course of action would be to use AES for encryption / decryption and HMACSHA256 for validation. This combination is FIPS-compliant and provides better security than 3DES / SHA1 (which is what was being used earlier). To do this, set:
<machineKey validation="HMACSHA256" validationKey="256 bits worth of hex digits (64 hex chars)" decryption="AES" decryptionKey="256 bits worth of hex digits (64 hex chars)" />
Then also set <pages viewStateEncryptionMode="Always" /> in Web.config to tell ASP.NET to use view state encryption using the algorithms you just provided in the <machineKey> element.

Key not valid for use in specified state after IISRESET

I have created a Custom STS Login Application and logging in/out functionalities were working fine. But if i login as some user and do IISRESET and then reloaded the page the below error is spitted. (But as expected it works fine after I cleared the cookies and logged in again :) )
Apppool user for STS Application is "A" and he has never windows logged into the server machine, where STS Application is deployed(he is in administrators group and has access to encryption certificates).
I tried to login once as "A" in to the server(Windows Login) and after that all of a sudden this issue is solved.
Can anyone tell why was it not working after IISRESET and working after windows logging in once?
Server Error in '/’ Application.
Key not valid for use in specified state.
[CryptographicException: Key not valid for use in specified state.]
System.Security.Cryptography.ProtectedData.Unprotect(Byte[] encryptedData, Byte[] optionalEntropy, DataProtectionScope scope)
Microsoft.IdentityModel.Web.ProtectedDataCookieTransform.Decode(Byte[] encoded)
[InvalidOperationException: 1D1073: A CryptographicException occurred when attempting to decrypt the cookie using the ProtectedData API (see inner exception for details).
Microsoft.IdentityModel.Web.ProtectedDataCookieTransform.Decode(Byte[] encoded) +433
Microsoft.IdentityModel .Tokens.SessionSecurityTokenHandler.ApplyTransforms(Byte] cookie, Boolean outbound) +189
Microsoft. IdentityModel .Tokens. SessionSecurityTokenHandler. ReadToken(XmlReader reader, SecurityTokenResolver tokenResolver) +894
Microsoft. IdentityModel .Tokens. SessionSecurityTokenHandler. ReadToken(Byte]] token, SecurityTokenResolver tokenResolver) +118
Microsoft.IdentityModel.Web.SessionAuthenticationModule.ReadSessionTokenrrocCookie(Byte] sessionCookie) +363
Microsoft.IdentityModel.Web. SessionAuthenticationModule.TryReadSessionTokenFroaCookie(SessionSecurityToken& sessionToken) +124
Microsoft. IdentityModel .Web. SessionAuthenticationModule.OnAuthenticateRequest(Object sender, EventArgs eventArgs) +61
System.Web.SyncEventExecutionstep.System.Web.HttpApplication.IExecutionStep.Execute() +80
System. Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +270
Version Information: Microsoft .NET Framework Version:4.D.30319; ASP NET Version:4.O.30319.272
If you're running with the default WIF config, the keys used to secure the session tokens are handled through DPAPI and are stored in the user profile. These keys change on iisreset unless you configure IIS with "Load User Profile" as true.
If you're running on .NET 4.5 the easiest approach would be to configure machineKeys for your application and use the new MachineKeySessionSecurityTokenHandler, as documented in Wif and Web Farms.

Viewstate Validation fails in web-farm - Usual suspects eliminated

I think that I've tried all of the standard responses to this problem, and I know that I've read hundreds of questions and posts about this problem, but none of them seem to have resolved it or shed any light on what the cause is in my scenario. (I'm 5 hours down and no nearer :-( )
I have a web-farm of 2 servers.
I have set the machine key and validation key in machine.config on both machines
Encryption: SHA1, Decryption: AES - These are the defaults, could it help to change them?
I have verified that no other config files in the chain (web.cfg, apphost etc.) have a setting for these values.
I have added a page to the site (based on this SO) that spits the machine key values back out, and verified that they are the same across requests to both machines and match the values that are in machine .config
The server side session state is in a shared state-server, I have verified that sessionid remains constant between requests to the 2 servers.
I have verified that the page is completely loaded and the __EVENTVALIDATION hidden field has been rendered into the page before initiating the post. The viewstate size is not too bad at 7.64kb
When a page is rendered from a request to server 1 and then posted back to server 2, I get the dreaded...
Error Message:
Unable to validate data.
at System.Web.Configuration.MachineKeySection.GetDecodedData(Byte[] buf, Byte[] modifier, Int32 start, Int32 length, Int32& dataLength)
at System.Web.UI.ObjectStateFormatter.Deserialize(String inputString) HttpApplication.RecordError => HttpApplication.RaiseOnError => global_asax.Application_Error
The post is triggered by a standard, unadulterated asp linkbutton, there is no ajax going on on the page.
Any and all help will be greatly appreciated.
Setting enableViewStateMAC = false is not a solution :-)
Having inherited the servers in the state that they were configured, I never questioned the validity of the keys!!! ...Just checked that they matched on both servers...
Leaving all the encryption / decryption and validation algorithm settings as they were, I generated new keys using this tool which has a few more options than the others.
Problem solved
Moral of the story: If in doubt, generate new keys
... but why and how? Some postbacks with viewstate were working just fine with the old keys, it was only when the postback was to a different server that the problem became evident. If the keys were invalid - missing a character or something - then every postback should have failed - I think
If you've established that the machine keys are the same on both boxes, could it be the encryption/decryption thereof ?
Have you tried using Triple DES and setting the decryptionKey in the machine.config on both servers?
Check here
Also a easy way of making sure the machineKeys are the same is to add a line like this in the web.config.
NB: Assuming you have the same web.config on both servers and making sure that the validationKey and decryptionKey is valid
You can use http://aspnetresources.com/tools/machineKey to generate it.
<system.web>
<machineKey validationKey="*D9B0EDEA69D81A89BF5FBA2B08BAF691013F86B89A1F6BA8068C6ECC9539074" decryptionKey="*AE2B1966AF65D08F03EDFB" validation="SHA1" decryption="AES" />

Forms Authentication 4.0 on Web Farm

This is quite literally driving me bananas - I'm on holiday as from tomorrow but if I can't get this working today then it's under threat - so any help much appreciated!
Firstly, my website has a manually defined <machinekey /> element defined so that both web servers in the web farm are kept in sync. I have verified this with IIS manager (hence why I'm asking, despite the similarity with so many other questions). It looks like this (keys elided - but they are the correct length):
<machineKey validationKey="[512 bit hex]"
decryptionKey="[256-bit hex]"
validation="SHA1"
decryption="AES" />
The website is running Asp.Net MVC3 and I am using Forms authentication in 'normal' mode (i.e. not 2.0 compat mode). I'm using Forms Authentication to create an authentication ticket - using code like the following:
FormsAuthentication.SetAuthCookie(userName, false);
My Forms Auth config is very simple; there are no IIS or server-wide settings in place that override the documented defaults:
<authentication mode="Forms">
<forms defaultUrl="~/Unauthorised"
loginUrl="~/Unauthorised"
ticketCompatibilityMode="Framework40" />
</authentication>
And then I've hijacked the cookie-reading functionality as per this MSDN topic so that I can create the principal and identity that I want.
Problem is - only one half of the web farm is able to decrypt the authentication cookie, the other half (i.e. whichever one didn't authenticate the user) just gives:
System.Security.Cryptography.CryptographicException: Length of the data to decrypt is invalid.
With this as the top-part of the stack trace:
[CryptographicException: Length of the data to decrypt is invalid.]
System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount) +12521039
System.Security.Cryptography.CryptoStream.FlushFinalBlock() +53
System.Web.Configuration.MachineKeySection.EncryptOrDecryptData(Boolean fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length, Boolean useValidationSymAlgo, Boolean useLegacyMode, IVType ivType) +331
System.Web.Security.FormsAuthentication.Decrypt(String encryptedTicket) +293
We are using a slightly ancient (but very reliable) Load balancer - which does not modify the HTTP traffic - and the traffic in this case is HTTPs; I'm able to verify that it's always one server and not both by having used Fiddler to decrypt and inspect the traffic.
This clearly points to out-of-sync machineKeys - but they are not - so any idea what's going on!!?
Thanks in advance!
When different servers have different patches, it has the potential to alter the behavior of encryption (/decryption), therefore possibly causing this runtime exception:
System.Security.Cryptography.CryptographicException: Length of the data to decrypt is invalid.
More information regarding this issue can be found here: http://blog.evonet.com.au/post/SystemSecurityCryptographyCryptographicException-Length-of-the-data-to-decrypt-is-invalid.aspx

ViewState and Security Settings generating errors

I have an odd reoccurring error that I believe is related to View State and security settings. This error appears on one of my client’s site between 1 to 6 times a day:
Source: System.Web
Error in: /detail.aspx?CaseID=1852
Error Message: Unable to validate data.
Stack Trace: at System.Web.Configuration.MachineKeySection.**EncryptOrDecryptData(**Boolean fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length, IVType ivType, Boolean useValidationSymAlgo)
at System.Web.UI.ObjectStateFormatter.Deserialize(String inputString)
Researching online has lead to a deadend. I believe it has do with security and ViewState. Because this is an ecommerce site, I took the extra steps of protecting against a number of treats, includign XSS and CSFR. Here are the steps I took:
Turned on HTTPOnly Cookies (Protects against XSS Style Attacks)
Turned on Secure Cookie Flag (Protects against XSS Style Attacks)
Created a BasePage which all the pages inherit instead of Page, in the Basepage I overrides OnInit and set ViewStateUserKey to SessionID (Protects against certain CSFR Style Attacks)
Explicitly enabled validateRequest (On by default, but can be overwritten)
ViewState Encryption Enabled
The website is hosted on a Win2003 Virtual Server, using ASP.NET 3.5 SP1 and AJAX. The page is not using caching, which some articles I found suggested was a problem when you set the ViewStateUserKey key to a unique value, such as SessionID. I can duplicate this exact error if I turn off cookies in my browser and try to view one of the pages that creates the error.
Notes, The error message does NOT mention MAC has failed
My theory is that those that experience this error are on networks that have a Proxy/Caching Server. My solution was to only set the ViewStateUserKey when it was a secure connection. Most Proxy/Caching Servers are only set to cache HTTP connections, not secure connections.

Resources