Reference URL:
Http://www.faqs.org/rfcs/rfc2617.html
Http://www.faqs.org/rfcs/rfc1321.html
Http://www.cnblogs.com/my_life/articles/2285649.html
Http://blog.sina.com.cn/s/blog_53b15ed5010006t9.html
Http://blog.chinaunix.net/uid-26212859-id-3485297.html
Http://blog.csdn.net/jackxinxu2100/article/details/5610448#reply
Http://www.vsharing.com/k/KM/2003-1/458471.html
Http://support.microsoft.com/kb/811318/zh-cn
The first five are important, and the first two are the most important.
A thttpd Web server is downloaded from the Internet as an embedded web service. After all the functions are completed, it is proposed that all functions based on the httpd protocol of the web service should be protected, that is, authentication. Then I started searching for relevant information on the Internet. After several days, I finally got it ready.
Basic authentication is not discussed here because basic authentication is too simple and directly transmitted in plain text.
I don't understand the meaning of digest or digest-challenge in rfc2617.
First of all, the following process is only based on my content description, which may not be comprehensive enough. Therefore, this article is for general reference only.
In general, the authentication process is: the client requests resources-> the server returns the authentication mark-> the client sends the authentication information-> the server checks and authenticates. If the authentication succeeds, the resource transmission continues; otherwise, the connection is directly disconnected.
The server returns the following authentication information:
WWW-Authenticate: Digest realm = "XX", qop = "auth, Auth-int", Nonce = "XX", opaque = "XX"
This part must be included in the HTTP header, that is, placed in front of the first blank line, and the double quotation marks are also transmitted together. The rfc2616 document also defines many other domains. Each domain is separated by a comma (,). We will not discuss them here. The colon ":" is not allowed in the values of each field, because the colon is a connector during MD5 encryption. In addition, all values must be visible characters, which is consistent with the requirements of HTTP. This part of the content is very strict. If it is difficult, the client may prompt errors, such as "protocol conflicts" and "denial of service ".
At the same time, the system returns the 401 unauthorized error.
The default value is MD5 encryption, and MD5 should be the most widely used. Therefore, you do not need to add the algorithm domain.
WWW-authenticate is a httpd header.
The realm value is a simple string, while rfc2617 writes an email string. I don't think this is necessary, so I simply wrote an email string.
Qop is the authentication (verification) method. This is important and affects the subsequent MD5 encryption process. The value can be written as shown above.
The Nonce value is also a string. If it is not strict, you can randomly generate one. Note that it is a guid, which is unique and non-repeated. If the authentication is strict, it must contain the time information, Client IP address information, and other information. Because the authentication process takes a short time, if the server receives the authentication information and finds that this time is far from the server time, it indicates that the connection is abnormal, and it is rejected directly to prevent attacks, as well as the Client IP address. If this IP address keeps attacking like this, the connection to this IP address can be found to be disconnected within a certain period of time. These strict practices are mainly used to prevent attacks. There is a detailed description of the narrow path on rfc2617. I didn't think about this here, but I used a simple string.
Opaque is a string. It is only passthrough, that is, the client will return it as it is. In fact, the above fields will still be returned by the client as is, but in addition to the above fields, new content will be added to the returned results.
After receiving the 401 error, the client needs to enter the user name and password Based on the above information, and then return the following content to the server:
Authorization: Digest username = "XX", realm = "XX", qop = "auth", Nonce = "XX", uri = "path", cnonce = "XX ", NC = 00000001, response = "XX", opaque = "XX"
Except for the different qop values, the values of other existing fields are the same. The newly added values are as follows:
Username is the user name to be authenticated
Uri is the resource location of this request, such as "/public/userinfo.htm"
Cnonce is a guid generated by the client, which is generally 32 bytes and expressed in hexadecimal form of a 16-byte string. Therefore, the content of cnonce is 0 ~ 9 and ~ The characters between F. In fact, the same is true for nonce, but I did not specifically do this. For example, I directly generate a number and then output it in hexadecimal format, without the special pursuit of 16 bytes.
NC is the number of authentications, because if the authentication fails, you can still resend the authentication information to continue the authentication. The first is 1, the second is 2, and the third is 3 ,.... But I didn't do this here, only one request is allowed. If the authentication fails, the connection is closed. So I only process 1, that is, 00000001. This value is always fixed to 8 bytes, without quotation marks, the format is different from that of other domains. As a result, I wrote a separate code when analyzing this domain. I don't know why it is different.
The value of response is very important. It is an MD5 code calculated based on the above information and the password in a certain order. It is fixed to a 16-byte hexadecimal representation. After receiving all this information, the server calculates this value in the same way, while the password is stored on the server side, that is, the server needs to find the corresponding password through the user name, then compare it with the calculated MD5 value and the response value passed by the client. If the value is the same, the authentication will pass. Otherwise, the authentication will fail.
The key is the calculation of the MD5 value, which is calculated using the values of each field (without double quotation marks at both ends ).
The formula is: MD5 = HA1: HD: ha2.
Note that this formula is simplified for ease of description and is not the same as that in other documents. Indicates performing MD5 Calculation on HA1: HD: ha2, the same below.
MD5 indicates the final calculated value, that is, the value of response.
Note that the colon ":" is also the content of the calculated string and a connector.
If the value of algorithm is "md5-sess ",
HA1 = Username: realm: Password: nonce: cnonce (1)
Otherwise
HA1 = Username: realm: Password (2)
Here I use (2)
If qop has a value (if (* pszqop ),
Hd = nonce: noncecount: cnonce: qop (3)
Otherwise
Hd = nonce (4)
Because I have a qop value here, I use (3)
Ha2 = method: URI
If the qop value is "Auth-int", the ha2 value is calculated differently. I don't know much about it and I don't use it, so I don't care about it.
Method refers to "get"/"Post", that is, the method specified in the HTTP header to obtain resources.
It should be noted that in the calculation process, sufficient internal allocation is required. Otherwise, exceeding the border may lead to changes in the string content. I found this problem only after one day, finally, I found an MD5-encrypted computing tool on the Internet and compared the computing results of each part to find out the problem.
In fact, I also found another address. The formula is well written and clear, but I didn't add it to my favorites later.