This article explains a simple way of implementing digest protocol in C#. A sample application is provided which shows how it is calculated in a step by step manner.
In HTTP protocol for authentication, we use different types of protocols: basic, digest and Kerberos.
1. Basic Authentication
This is most unsecured because it uses plain text transfer of both userid and password to the server.
2. Digest Authentication
This method provides safety up to a certain level. The password is not passed by the client, instead server and client generate a 32 bit key with that password is hashed by a defined algorithm. The communication is attribute value strings and lots of parameters are optional. Due to this, it is vulnerable for middle level hackers who can hack the string and alter it with basic authentication or remove some of the digest optional values.
This is considered one of the most secured ways. Authentication is not done in one or two steps. The challenge and response is a process of few steps with tickets for each stage. If the communication breaks for some reason, it has to start from the first stage. Due to this, vulnerability is less. But the process is a long one.
In this article, we talk about digest protocol and how we implement it using .NET Framework 3.5.
Here we talk about server side handling of protocol only. First the request is sent by the server with these parameters.
Realm=Name of the realm
Nonce=Generated every time a 32 bit hexadecimal representation of character
Stale=true/false (is it repeated call or 1<sup>st</sup> time call)
QOP=auth (another method is auth-integer)
The client receives the information and it will prompt user for userid and password. User will be giving her/his user id and password. Then the user will press login. When the user presses login, the application will do hashing with the given and some additional parameters. It will send the hashed information and parameter back to the server.
The password will not be sent back by the client, instead it will MD5 hash the password with given parameters and the generated parameters. Now the server has to use the data sent by the client. In addition to that, we have to get the password for the userid from the SQL database. It is quite simple to get the password from Database using the userid. The method name is implementation specific, in my case it’s “
Now you have client given parameters including userid and we retrieved the password from the database. Now we have to apply the algorithm.
Separate the parameters sent by the client and store it into named variables. In the sample, we are doing that with:
private void SplitResponse(String strResponse, out String strUserName,
out String StrSplResponse, out String strRealm,out String strURI,
out String strNonce, out String strCnonce, out String strNonceCount,
out String strQop
Have a hashing function that follows MD5 hashing:
private String GetHash(String strIn)
Now we do algorithm implementation. Format the strings one by one.
To get A1:
UserName + ":" + Realm + ":" + Password
A1Hash = Hash the A1 value
To get A2:
CommandName + ":" + URI
A2Hash = A2 MD5 has it.
Now calculate the response:
A1Hash + ":" + CNonce + ":" + NonceCount + ":" + QOP + ":" + A2Hash
Now hash this response value and check with client return response, it should be equal means the user has entered the proper password and we can allow a token. Otherwise authentication is denied.
Sample Data Send by Client
Server code which will retrieve (using SQL server / any database):
- Password: testpass
- Method: DESCRIBE
The result response must be equal to “47aa3643329845a954a2d091422eb35f”.
I have attached a sample program which demonstrates how to implement MD5 hashing and digest authentication.
The sample solution can be used as a sample calculator when you want to implement it in another language or another technology. We can use this article as a step by step checking tool.
- 24th October, 2008: Initial post