Java [Algorithm 04] HTTP authentication method DIGEST authentication detailed process description and examples

Detailed documentation: WWW-Authenticate - HTTP | MDN (mozilla.org)

1.What is

Digest Authentication is an authentication method used to verify user identity in network communications. It is mainly used in HTTP and other application layer protocols.

Digest authentication is more secure than basic authentication because it does not directly transmit clear text passwords. But it's not a complete security solution either, as it's still possible to be attacked in situations like man-in-the-middle attacks. In modern networks, a more secure authentication method is usually a token-based authentication mechanism.

2. Valuation process

Similar to Basic certification process:

Insert image description here

The overall process of Digest certification is as follows:

  1. The client sends a request: The client sends a request to the server, and the request contains the path to the resource that needs to be accessed.

  2. The server returns challenge information: After receiving the client's request, the server returns a "challenge" information (Challenge) to the client. This challenge information is a string containing a random number, realm name, and other parameters.

  3. Client generates response: The client uses the username, password, and challenge information to generate a response string. The generation process of this response string includes the following steps:

    • Concatenation: Separate the username, realm name, and password with colons and concatenate them into a string.
    • Hash the string: Hash the above concatenated string, usually using hashing algorithms such as MD5 or SHA-1.
  4. The client sends a response: The client sends the generated response string to the server and puts it in the "Authorization" header of the request.

  5. Server verification response: After the server receives the client's response, it uses the same method to regenerate the response string on the server side. The response string sent by the client is then compared with the response string generated by the server. If they are equal, the client has the correct username and password.

  6. The server returns a response: If the server authenticates successfully, it will return the requested resource content to the client, and include an identification of successful authentication in the response header.

2.1 Client sends request

The client's first request.

2.2 The server returns the challenge information

2.2.1 Challenge parameters

  • qop: A quoted string indicating the level of protection supported by the server. This must be provided, and unrecognized options must be ignored.

    • "auth":Authentication
    • "auth-int": Fully protected authentication
  • nonce: A server-specified quoted string that the server can use to verify the specified credentials during each 401 response. This must be uniquely generated on each 401 response, and may be regenerated more frequently (e.g., allowing a digest to be used only once). This specification contains recommendations on the algorithm for generating this value. The nonce value is opaque to the client.

  • opaque: A server-specified quoted string that should be Authorizationreturned unchanged in . This is opaque to the client. It is recommended that the server contains Base64 or hexadecimal data.

  • <realm>(Optional) A string indicating the username/password to use. At a minimum, the host name should be included, but may indicate users or groups with access.

  • domain(Optional) A quoted, space-separated list of URI prefixes that defines all locations where authentication information can be used. If this keyword is not specified, the authentication information can be used anywhere in the web root.

  • stale(Optional) A case-insensitive flag indicating to the client that the previous request noncewas rejected because it was too old (expired). If so , you can retry the request trueusing the new encrypted same username/password. nonceIf it is any other value, the username/password is invalid and must be re-requested from the user.

  • algorithm(Optional) The algorithm used to generate a summary. Valid non-session values ​​are: "MD5"(default if not specified), "SHA-256", "SHA-512". Valid session values ​​are: "MD5-sess", "SHA-256-sess", "SHA-512-sess".

  • charset="UTF-8"(Optional) Tell the client the server's preferred encoding scheme when submitting a username and password. The only allowed values ​​are case-insensitive "UTF-8" strings.

  • userhash(Optional) The server may be specified "true"as to indicate that it supports username hashing (default is "false").

2.2.2 Questioning examples

The client is trying to access http://www.example.org/dir/index.htmlthe document at , which is protected by digest authentication. The username for this document is "Mufsas" and its password is "Circle of Life". The first time a client requests the document, no Authorizationheader fields are sent. Here, the server responds with an HTTP 401 message that includes a challenge for each digest algorithm it supports, in order of precedence ( SHA256, then MD5).

The server puts the challenge information in the WWW-Authenticate response header and sends it to the client, as shown in the following example:

HTTP/1.1 401 Unauthorized

WWW-Authenticate: Digest
    realm="[email protected]",
    qop="auth, auth-int",
    algorithm=SHA-256,
    nonce="7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v",
    opaque="FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS"

WWW-Authenticate: Digest
    realm="[email protected]",
    qop="auth, auth-int",
    algorithm=MD5,
    nonce="7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v",
    opaque="FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS"

2.3 Client generates response

The client receives a 401 response indicating that authentication is required, the client prompts the user for their username and password, and then responds with a new request that encrypts the credentials in the Authorizationheader field. If the client chooses MD5 digest, Authorizationthe header fields might look like this:

Authorization: Digest username="Mufasa",
    realm="[email protected]",
    uri="/dir/index.html",
    algorithm=MD5,
    nonce="7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v",
    nc=00000001,
    cnonce="f2/wE4q74E6zIJEtWaHKaf5wv/H5QzzpXusqGemxURZJ",
    qop=auth,
    response="8ca523f5e9506fed4657c9700eebdbec",
    opaque="FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS"

If the client chooses SHA-256 digest, Authorizationthe header might look like this:

Authorization: Digest username="Mufasa",
    realm="[email protected]",
    uri="/dir/index.html",
    algorithm=SHA-256,
    nonce="7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v",
    nc=00000001,
    cnonce="f2/wE4q74E6zIJEtWaHKaf5wv/H5QzzpXusqGemxURZJ",
    qop=auth,
    response="753927fa0e85d155564e2e272a28d1802ca10daf4496794697cf8db5856cb6c1",
    opaque="FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS"

2.4 Server verification response

After the server receives the client's response, it uses the same method to reproduce the response string on the server side. The response string sent by the client is then compared with the response string generated by the server. If they are equal, the client has the correct username and password.

2.5 The server returns a response

If the server authenticates successfully, it will return the requested resource content to the client and include an identification of successful authentication in the response header.

3. Algorithm

According to the value in the request body algorithm:

HTTP/1.1 401 Unauthorized

WWW-Authenticate: Digest
    realm="[email protected]",
    qop="auth, auth-int",
    algorithm=SHA-256,
    nonce="7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v",
    opaque="FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS"

The following is the description in the standard document, from RFC 7616: HTTP Digest Access Authentication (rfc-editor.org) :

A string indicating an algorithm used to produce the digest and an unkeyed digest. If this is not present, it is assumed to be “MD5”. If the algorithm is not understood, the challenge SHOULD be ignored (and a different one used, if there is more than one). When used with the Digest mechanism, each one of the algorithms has two variants: Session variant and non-Session variant. The non-Session variant is denoted by “”, e.g., “SHA-256”, and the Session variant is denoted by “-sess”, e.g., “SHA-256-sess”.

In this document, the string obtained by applying the digest algorithm to the data “data” with secret “secret” will be denoted by KD(secret, data), and the string obtained by applying theunkeyed digest algorithm to the data “data” will be denoted H(data). KD stands for Keyed Digest, and the notation unq(X) means the value of the quoted-string X without the surrounding quotes and with quoting slashes removed.

For "<algorithm>" and "<algorithm>-sess"
	H(data) = <algorithm>(data)
and
	KD(secret, data) = H(concat(secret, ":", data))

For example:

For the "SHA-256" and "SHA-256-sess" algorithms
	H(data) = SHA-256(data)
	
For the "MD5" and "MD5-sess" algorithms 
	H(data) = MD5(data)

i.e., the digest is the “” of the secret concatenated with a colon concatenated with the data. The “-sess” is intended to allow efficient third-party authentication servers; for the difference in usage, see the description in Section 3.4.2.

A brief explanation:

  • KD (secret, data) is the algorithm encryption after concatenating secretand datawith a colon.:secret:data
  • H(data) is to directly encrypt the data with the algorithm
  • unq(username) is a string without quotes

3.1 SHA-256

We can refer to RFC 7616: HTTP Digest Access Authentication (rfc-editor.org)

3.1.1 Response

If the qop value is “auth” or “auth-int”:

response = KD(H(A1),unq(nonce):nc:unq(cnonce):unq(qop):H(A2))

See below for the definitions for A1 and A2.

3.1.2 A1

If the algorithm parameter’s value is “”, e.g., “SHA-256”,then A1 is:

A1 = unq(username):unq(realm):passwd
where passwd = < user's password >

If the algorithm parameter’s value is “-sess”, e.g., “SHA-256-sess”, then A1 is calculated using the nonce value provided in the challenge from the server, and cnonce value from the request by the client following receipt of a WWW-Authenticate challenge from the server. It uses the server nonce from that challenge, herein called nonce-prime, and the client nonce value from the response, herein called cnonce-prime, to construct A1 as follows:

A1 = H(unq(username):unq(realm):passwd):unq(nonce-prime):unq(cnonce-prime)

This creates a “session key” for the authentication of subsequent requests and responses that is different for each “authentication session”, thus limiting the amount of material hashed with any one key. (Note: see further discussion of the authentication session in Section 3.6.) Because the server needs only use the hash of the user credentials in order to create the A1 value, this construction could be used in conjunction with a third-party authentication service so that the web server would not need the actual password value. The specification of such a protocol is beyond the scope of this specification.

3.1.3 A2

If the qop parameter’s value is “auth” or is unspecified, then A2 is:

A2 = Method:request-uri

If the qop value is “auth-int”, then A2 is:

A2 = Method:request-uri:H(entity-body)

3.2 MD5

We can refer to RFC 2617 - HTTP Authentication: Basic and Digest Access Authentication (ietf.org)

3.2.1 Request-Digest

If the “qop” value is “auth” or “auth-int”:

request-digest = KD(H(A1), unq(nonce-value):nc-value:unq(cnonce-value):unq(qop-value):H(A2))

If the “qop” directive is not present (this construction is for compatibility with RFC 2069):

request-digest = KD(H(A1), unq(nonce-value):H(A2))

See below for the definitions for A1 and A2.

3.2.2 A1

If the “algorithm” directive’s value is “MD5” or is unspecified, then A1 is:

A1 = unq(username-value):unq(realm-value):passwd
where passwd = < user's password >

If the “algorithm” directive’s value is “MD5-sess”, then A1 is calculated only once - on the first request by the client following receipt of a WWW-Authenticate challenge from the server. It uses the server nonce from that challenge, and the first client nonce value to construct A1 as follows:

A1 = H(unq(username-value):unq(realm-value):passwd):unq(nonce-value):unq(cnonce-value)

This creates a ‘session key’ for the authentication of subsequent requests and responses which is different for each “authentication session”, thus limiting the amount of material hashed with any one key. (Note: see further discussion of the authentication session in section 3.3.) Because the server need only use the hash of the user credentials in order to create the A1 value, this construction could be used in conjunction with a third party authentication service so that the web server would not need the actual password value. The specification of such a protocol is beyond the scope of this specification.

3.2.3 A2

If the “qop” directive’s value is “auth” or is unspecified, then A2 is:

A2 = Method:digest-uri-value  

If the “qop” value is “auth-int”, then A2 is:

A2 = Method:digest-uri-value:H(entity-body)

4.Examples

We also use the above example to perform algorithm processing. algorithmIf no value is assigned, it is the default MD5. The user name is still used Mufasa, and the password is used 123456:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Digest
    realm="[email protected]",
    qop="auth",
    nonce="7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v",
    opaque="FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS"

response:

Authorization: Digest username="Mufasa", 
	realm="[email protected]", 
	uri="/dir/index.html", 
	algorithm=MD5, 
	nonce="7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v", 
	nc=00000001, 
	cnonce="nvlfh1ra", 
	qop=auth, 
	response="7bddc3c7fceb317dc002c524187fa170", 
	opaque="FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS"

Complete algorithm, here we must pay great attention to whether there are double quotes:

// A1 = unq(username-value):unq(realm-value):passwd
String A1 = StrUtil.format("{}:{}:\"{}\"", "Mufasa", "[email protected]", "123456");
// A2 = Method:digest-uri-value
String A2 = StrUtil.format("\"{}\":\"{}\"", "POST", "/dir/index.html");
// request-digest = KD(H(A1), unq(nonce-value):nc-value:unq(cnonce-value):unq(qop-value):H(A2))
String HA1 = SecureUtil.md5(A1);
String HA2 = SecureUtil.md5(A2);
String responseStr = StrUtil.format("\"{}\":{}:\"{}\":{}:{}:\"{}\"", HA1, "7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v","00000001", "nvlfh1ra", "auth", HA2);
String response = SecureUtil.md5(responseStr);

Guess you like

Origin blog.csdn.net/weixin_39168541/article/details/132234634