I have a .Net 1.1 app that must be upgraded to 2.0. The application encrypts passwords in the database using MD5CryptoServiceProvider. After I upgraded to 2.0, the MD5 value was different. In the machine.config, the machinekey was set to autogenerate.
Is there a way to retrieve this key?
Yes, you can with a bit of reflection, see here for details and code :)
Though, I'm not sure that MD5CryptoServiceProvider actually uses the machine key, I thought it was independent, someone correctly me in comments?
The System.Security.Cryptography.MD5CryptoServiceProvider doesn't rely on the ASP.NET system.web/machineKey settings. These are used to control tamper proofing and encryption of ViewState, forms authentication tickets, and role cookies (How To: Configure MachineKey in ASP.NET 2.0).
I just compiled a simple console application under .NET 1.1 and 2.0 that performs a MD5 hash and they both produce the same value. I ran these applications on two different machines (one with autogenerated machine keys, and one with hard coded keys), again, identical results.
This sounds like the Encoding used is possibly different, i.e. the 1.1 application is using ASCIIEncoding and the 2.0 application is using Unicode.
Another thing to check is if the method you're using a uses salt that you've forgotten about, that would certainly cause different hashes to be generated.
Related
We have ASP.NET ( Silverlight) LOB Web application which was developed using .Net 4. Now we have to get rid of the current authentication mechanism and implement new one. I think we have two options here:
1> Forms Authentication using Membership provider ( This is available in .Net 4)
2> ASP.NET Identity ( This is not available in .Net 4. So we have to update the target framework to 4.5 or latter)
I have gone through the article here that describes the difference between these two and based on my understanding the 2 major differences are:
1> You can configured identity framework to use social credentials.
2> Identity framework code can be unit tested.
We have LOB application. So likelihood of allowing users to use their social credential to login into our application is very very less. So i am looking for suggestion whether it is really worthwhile to spend time and implement identity framework for authentication. (Note that for identity framework I will have to convert target framework of all projects to 4.5). The only advantage I see here is unit testing.
Updating to later framework is not a problem. Going back the way usually causes problem, but you won't have to do any code changes if you go from 4 to 4.5. Or rather 4.5.1 which is latest in 4.5.x.
If architecture advantage is not an advantage to you, then security must be. Identity uses PBKDF2 with HMAC-SHA256 password hashing. This is not available in MembershipProvider which comes with SHA1 as default hashing which is not considered secure at all in 2016
Otherwise I enjoy working with Identity framework - it is a lot easier to do things with rather than monstrous MembershipProvider. Some things took me few hours to implement in Identity that took weeks with MembershiProvider. So speed of development is another consideration.
Also MembershipProvider is not getting any new versions, why do you want to use old framework when a new shiny supported framework is available?
I'm using oracle asp.net Forms Auth in my web app. The asp.net Membership/Role/Profile provider classes use Oracle.web.dll, and the connection string for these use Oracle.DataAccess.dll.
Now I want to change to Oracle.ManagedDataAccess.dll for the main application's data connection.
I made this change, and the app's main data connections work fine. However when any of the Forms Membership/Role/Profile methods are called, I get errors saying "Failed to load Oracle.DataAccess.dll".
I pointed the Forms Auth connections strings to a string using the Managed provider, but the Membership/Role/Profile parts seem to rely on Oracle.Web, which somehow looks for Oracle.DataAccess instead of the Oracle.ManagedDataAccess.
Can anyone shed light on this please?
Thanks,
--Jim
I ran into a similar problem and used Reflector to check references.
Yes, Oracle.Web.dll references Oracle.DataAccess.dll which further references OCI. Since OCI different for 64bit and 32bit one actually needs to install the appropriate Oracle client.
Hope that there will be a Oracle.Web version, that relies on Oracle.ManagedDataAcccess.dll soon.
The advantage of thru the use of oracle.manageddataaccess is kind of lost if one relies on profiles or membership providers.
I have an application running ASP.NET on 3.0 framework that uses form authentication. I am now building and MVC 4 application that also uses forms authentication and I would like to share authentication between the two apps. I have both config files matching for the auth tag and exact machine key tags. I think my problem is that the ASP.NET application uses the old ASP membership provider which has the user passwords in MD5 format, and the MVC application is using simple membership, password format SHA1.
Is there a way to share user authentication between the two apps even with different credentials(password formats)?
For the main app that authenticates in the forms tag I have this
<credentials passwordFormat="MD5"/>
I am not really sure if this is my issue or what's going on.
Well figured out my answer. All I had to do was add in the tag was the attribute compatibilityMode="Framework20SP2".
This was due to the fact my ASP.NET app was running on the older framework and my new MVC app was on framework 4.0
Your options are pretty much:
Write your own ASP.Net 2.0 MembershipProvider to use the PBKDF2 algorithm to store passwords (Resetting everyone's passwords will be required).
You don't get to override SimpleMembershipProviders storage of passwords (that I know of) so you'll have to writing your own ExtendedMembershipProvider to duplicate the ASP.Net 2.0 security mechanisms in the default MembershipProvider.
As a side note, MD5 is (in my opinion) a terrible algorithm to store passwords. At this point from what I've read bcrypt or PBKDF2 is recommended by most security experts.
If you're interested on the changes Microsoft made to increase security in .Net releases the article Stronger Password Hashing in .NET with Microsoft’s Universal Providers is a good read.
I heard that the hashing algorithm for asp.net membership is sha-1, but I've seen in most articles that it is no longer safe, also I would like to know if most professional developers are using asp.net membership or do they come up with their own solution/ implementation with regards to login, authentication, authorization of their system/projects.
Does asp.net membership really provide a secure and robust solution for login, authentication, authorization of web applications? :)
The reason why I'm asking is I would like to know if developers are really using it in their projects.
Sir/Ma'am, Your answers would be of great help.
If I am writing internal applications with a modest number of users then I usually rely on asp.net memberhsip. Its familiar, I know how to get it up and running quickly. Other developers also know it reasonably well so it doesn't need explaining. Its also usually desirable for the organisation to be in control of user accounts.
On the other hand, if you were creating a public site and needed to authenticate users before making contributions (eg. stack overflow), you might want to think about implementing OpenId so users don't have to create a new account with your domain. They could use Google/Facebook/Twitter instead. There are libraries to get you started.
The default hash algorithm changed in .NET 4.0 to SHA256. So you are pretty safe if you are using .NET 4.0.
You could also specify the hash algorithm in your web.config:
<system.web>
<machineKey validation="SHA256" />
<membership defaultProvider="myMembership" hashAlgorithmType="SHA256">
...
</system.web>
Actually that's was a breaking change in .NET 4.0. So if you had an existing application in .NET 3.5 and upgraded to .NET 4.0 passwords that were hashed with SHA1 might no longer be used in .NET 4.0 unless you change the algorithm type back to SHA1.
Not really. ASP.NET membership provider is a design failure.
It forces you to use predefined domain model entities instead of
using your own.
Not interchangeable with ease (Use different providers per company or different forms of authentication)
The predefined MembershipProvider abstraction is a failed class design.(out param ? - yes, please test it)
Go implement your own provider.
For passwords choose your hash algorithm (sha1, sha512...).
After finishing the implementation use FormsAuthentication class to integrate it with your provider.
I have an ASP.NET system with a structure like this, hosting both .Net 1.1 and .Net 2.0 apps on the same server:
/apps11/app1
/apps11/app2
/apps11/web.config
/apps20/app3
/apps20/app4
/apps20/web.config
These above two web.config files have sections specific to their version of .Net, but the parts that relate to forms authentication and machine key were identical (so that the forms authentication cookie could be shared between apps on different versions). The section is shown below (with real key obfuscated but exact length and settings preserved):
<machineKey
validationKey="AAAABBBBCCCCDDDDEEEEFFFF0000111122223333"
decryptionKey="BBBB9999AAAA1111"
validation="SHA1">
</machineKey>
<authentication mode="Forms">
<forms name=".ASPXAUTH" protection="All" timeout="15" path="/" loginUrl="/apps20/login.aspx"></forms>
</authentication>
After an upgrade of the login page component of the app, the shared authentication stopped working for the 1.1 apps. I could log in to the 2.0 apps but when I navigated to a 1.1 app it would continually redirect me back to the login page. Went through the following troubleshooting steps:
An issue with MS10-070 and needing the KB243375 patch? It had already been applied on the server.
Machinekey broken by the installer? I checked the machinekey values and the installer had updated the validationKey and encryptionKey values. However, the settings remained the same (validation="SHA1") and the same machinekey was in both web.config files.
Some other value in machine.config or web.config for each .Net Framework version? Found a domain setting in the .Net 2.0 web.config, but that seemed to only impact the domain of the ticket cookie, not the content of it.
Problem with encryption settings between 1.1 and 2.0 as described in How To Share Authentication Cookies across ASP.NET V1.1 and ASP.NET V2.0 Applications? Nothing had changed except the key values, so why would it break now?
Answering my own question. This many years after .Net 1.1, I doubt many other people will need this info, but putting it out here just in case...
In the end, the problem was indeed #4 above. Not only the keys had changed, but also the length of the keys:
<machineKey
validationKey="EEEEEEEE77778888999900001111AAAABBBBCCCCDDDDFFFFAAAABBBBCCCCDDDDEEEEFFFF1111222233334444555566667777888899990000AAAABBBBCCCCDDDD"
decryptionKey="888899990000111122223333444455556666777788889999" validation="SHA1">
</machineKey>
The clue came in this Security via in ASP.NET 2.0 article, which says "The decryption attribute is a new addition in ASP.NET 2.0 to reduce the overloading of the older version of the validation attribute. The Auto option for this attribute uses an algorithm that is inferred from the key size. Triple DES encryption is the default, but a key of 128 or 256 bits will use AES."
Adding encryption="3DES" to my machineKey tag in the .Net 2.0 web.config solved the issue. It worked for years because the old key was short enough that it inferred 3DES. The new key was long enough that it inferred AES.
I went back and read the MSDN documentation for the machineKey element. It simply says "ASP.NET determines which decryption algorithm to use, based on configuration settings". And while later in the topic it tells you what length of key to use for each encryption type, it doesn't say that the encryption type is inferred from the length. In fact, it tells you how to use a shorter key than the recommended length (not sure why you'd want to).
Any better solutions to this? Am I the only one who thinks the MSDN doc is somewhat lacking on this point?