Método de autenticación HTTP DIGEST
Documentación detallada: WWW-Authenticate - HTTP | MDN (mozilla.org)
1. ¿Qué es?
La autenticación implícita es un método de autenticación que se utiliza para verificar la identidad del usuario en las comunicaciones de red. Se utiliza principalmente en HTTP y otros protocolos de capa de aplicación.
La autenticación implícita es más segura que la autenticación básica porque no transmite directamente contraseñas de texto sin cifrar. Pero tampoco es una solución de seguridad completa, ya que aún es posible sufrir ataques en situaciones como ataques de intermediario. En las redes modernas, un método de autenticación más seguro suele ser un mecanismo de autenticación basado en tokens.
2. Proceso de valoración
Similar al proceso de certificación Básico:
El proceso general de certificación Digest es el siguiente:
-
El cliente envía una solicitud: el cliente envía una solicitud al servidor y la solicitud contiene la ruta al recurso al que se debe acceder.
-
El servidor devuelve información de desafío: después de recibir la solicitud del cliente, el servidor devuelve información de "desafío" (Desafío) al cliente. Esta información de desafío es una cadena que contiene un número aleatorio, un nombre de dominio y otros parámetros.
-
El cliente genera una respuesta: el cliente utiliza el nombre de usuario, la contraseña y la información del desafío para generar una cadena de respuesta. El proceso de generación de esta cadena de respuesta incluye los siguientes pasos:
- Concatenación: separe el nombre de usuario, el nombre del dominio y la contraseña con dos puntos y concatenelos en una cadena.
- Hash de la cadena: Hash de la cadena concatenada anterior, generalmente utilizando algoritmos de hash como MD5 o SHA-1.
-
El cliente envía una respuesta: el cliente envía la cadena de respuesta generada al servidor y la coloca en el encabezado "Autorización" de la solicitud.
-
Respuesta de verificación del servidor: después de que el servidor recibe la respuesta del cliente, utiliza el mismo método para regenerar la cadena de respuesta en el lado del servidor. Luego, la cadena de respuesta enviada por el cliente se compara con la cadena de respuesta generada por el servidor. Si son iguales, el cliente tiene el nombre de usuario y contraseña correctos.
-
El servidor devuelve una respuesta: si el servidor se autentica exitosamente, devolverá el contenido del recurso solicitado al cliente e incluirá una identificación de autenticación exitosa en el encabezado de la respuesta.
2.1 Cliente envía solicitud
La primera petición del cliente.
2.2 El servidor devuelve la información del desafío.
2.2.1 Parámetros del desafío
-
qop: una cadena entre comillas que indica el nivel de protección admitido por el servidor. Esto debe proporcionarse y las opciones no reconocidas deben ignorarse.
-
"auth"
:Autenticación"auth-int"
: Autenticación totalmente protegida
-
nonce: una cadena entre comillas especificada por el servidor que el servidor puede usar para verificar las credenciales especificadas durante cada respuesta 401. Esto debe generarse de forma única en cada respuesta 401 y puede regenerarse con más frecuencia (por ejemplo, permitiendo que un resumen se use solo una vez). Esta especificación contiene recomendaciones sobre el algoritmo para generar este valor. El valor nonce es opaco para el cliente.
-
opaco: una cadena entre comillas especificada por el servidor que debe
Authorization
devolverse sin cambios en . Esto es opaco para el cliente. Se recomienda que el servidor contenga datos Base64 o hexadecimales. -
<realm>
(Opcional) Una cadena que indica el nombre de usuario/contraseña que se utilizará. Como mínimo, se debe incluir el nombre del host, pero puede indicar usuarios o grupos con acceso. -
domain
(Opcional) Una lista de prefijos de URI separados por espacios entre comillas que define todas las ubicaciones donde se puede utilizar la información de autenticación. Si no se especifica esta palabra clave, la información de autenticación se puede utilizar en cualquier lugar de la raíz web. -
stale
(Opcional) Un indicador que no distingue entre mayúsculas y minúsculas que indica al cliente que la solicitud anteriornonce
fue rechazada porque era demasiado antigua (vencida). Si es así , puede volver a intentar la solicitudtrue
utilizando el nuevo nombre de usuario y contraseña cifrados.nonce
Si es cualquier otro valor, el nombre de usuario/contraseña no es válido y debe volver a solicitarse al usuario. -
algorithm
(Opcional) El algoritmo utilizado para generar un resumen. Los valores válidos que no son de sesión son:"MD5"
(predeterminado si no se especifica),"SHA-256"
,"SHA-512"
. Los valores de sesión válidos son:"MD5-sess"
,"SHA-256-sess"
,"SHA-512-sess"
. -
charset="UTF-8"
(Opcional) Indique al cliente el esquema de codificación preferido del servidor al enviar un nombre de usuario y contraseña. Los únicos valores permitidos son cadenas "UTF-8" que no distinguen entre mayúsculas y minúsculas. -
userhash
(Opcional) El servidor se puede especificar"true"
para indicar que admite el hash de nombre de usuario (el valor predeterminado es"false"
).
2.2.2 Ejemplos de preguntas
El cliente está intentando acceder http://www.example.org/dir/index.html
al documento en , que está protegido mediante autenticación implícita. El nombre de usuario de este documento es "Mufsas" y su contraseña es "Círculo de Vida". La primera vez que un cliente solicita el documento, no Authorization
se envían campos de encabezado. Aquí, el servidor responde con un mensaje HTTP 401, que incluye un desafío para cada algoritmo de resumen que admite, en orden de prioridad ( SHA256
, luego MD5
).
El servidor coloca la información del desafío en el encabezado de respuesta WWW-Authenticate y lo envía al cliente, como se muestra en el siguiente ejemplo:
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 El cliente genera respuesta
El cliente recibe una respuesta 401 que indica que se requiere autenticación, solicita al usuario su nombre de usuario y contraseña y luego responde con una nueva solicitud que cifra las credenciales en el Authorization
campo del encabezado. Si el cliente elige el resumen MD5, Authorization
los campos del encabezado podrían verse así:
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"
Si el cliente elige el resumen SHA-256, Authorization
el encabezado podría verse así:
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 Respuesta de verificación del servidor
Una vez que el servidor recibe la respuesta del cliente, utiliza el mismo método para reproducir la cadena de respuesta en el lado del servidor. Luego, la cadena de respuesta enviada por el cliente se compara con la cadena de respuesta generada por el servidor. Si son iguales, el cliente tiene el nombre de usuario y contraseña correctos.
2.5 El servidor devuelve una respuesta
Si el servidor se autentica exitosamente, devolverá el contenido del recurso solicitado al cliente e incluirá una identificación de autenticación exitosa en el encabezado de respuesta.
3. Algoritmo
Según el valor en el cuerpo de la solicitud 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"
La siguiente es la descripción en el documento estándar, de RFC 7616: Autenticación de acceso implícito HTTP (rfc-editor.org) :
Una cadena que indica un algoritmo utilizado para producir el resumen y un resumen sin clave. Si no está presente, se supone que es "MD5". Si no se comprende el algoritmo, DEBE ignorarse el desafío (y usarse uno diferente, si hay más de uno). Cuando se utiliza con el mecanismo Digest, cada uno de los algoritmos tiene dos variantes: variante de sesión y variante sin sesión. La variante que no es de sesión se indica con “”, por ejemplo, “SHA-256”, y la variante de sesión se indica con “-sess”, por ejemplo, “SHA-256-sess”.
En este documento, la cadena obtenida al aplicar el algoritmo de resumen a los datos "datos" con secreto "secreto" se indicará como KD (secreto, datos), y la cadena obtenida al aplicar el algoritmo de resumen sin clave a los datos "datos" se denotará H (datos). KD significa Keyed Digest, y la notación unq(X) significa el valor de la cadena entre comillas X sin las comillas circundantes y sin las barras diagonales.
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)
es decir, el resumen es el "" del secreto concatenado con dos puntos concatenados con los datos. El "-sess" tiene como objetivo permitir servidores de autenticación de terceros eficientes; para conocer la diferencia de uso, consulte la descripción en la Sección 3.4.2.
Una breve explicación:
- KD (secreto, datos) es el algoritmo de cifrado después de concatenar
secret
ydata
con dos puntos.:
secret:data
- H (datos) es cifrar directamente los datos con el algoritmo.
- unq(nombre de usuario) es una cadena sin comillas
3.1 SHA-256
Podemos consultar RFC 7616: Autenticación de acceso implícito HTTP (rfc-editor.org)
3.1.1 Respuesta
Si el valor de qop es "auth" o "auth-int":
response = KD(H(A1),unq(nonce):nc:unq(cnonce):unq(qop):H(A2))
Consulte a continuación las definiciones de A1 y A2.
3.1.2 A1
Si el valor del parámetro del algoritmo es "", por ejemplo, "SHA-256", entonces A1 es:
A1 = unq(username):unq(realm):passwd
where passwd = < user's password >
Si el valor del parámetro del algoritmo es "-sess", por ejemplo, "SHA-256-sess", entonces A1 se calcula utilizando el valor nonce proporcionado en el desafío del servidor y el valor cnonce de la solicitud del cliente después de recibir un Desafío de autenticación WWW desde el servidor. Utiliza el nonce del servidor de ese desafío, denominado aquí nonce-prime, y el valor nonce del cliente de la respuesta, denominado aquí cnonce-prime, para construir A1 de la siguiente manera:
A1 = H(unq(username):unq(realm):passwd):unq(nonce-prime):unq(cnonce-prime)
Esto crea una "clave de sesión" para la autenticación de solicitudes y respuestas posteriores que es diferente para cada "sesión de autenticación", limitando así la cantidad de material codificado con cualquier clave. (Nota: consulte más información sobre la sesión de autenticación en la Sección 3.6.) Debido a que el servidor solo necesita usar el hash de las credenciales del usuario para crear el valor A1, esta construcción podría usarse junto con un servicio de autenticación de terceros para que que el servidor web no necesitaría el valor de contraseña real. La especificación de dicho protocolo está más allá del alcance de esta especificación.
3.1.3 A2
Si el valor del parámetro qop es "auth" o no está especificado, entonces A2 es:
A2 = Method:request-uri
Si el valor de qop es "auth-int", entonces A2 es:
A2 = Method:request-uri:H(entity-body)
3.2 MD5
Podemos referirnos al RFC 2617 - Autenticación HTTP: Autenticación de acceso básico y implícito (ietf.org)
3.2.1 Solicitud-Resumen
Si el valor de "qop" es "auth" o "auth-int":
request-digest = KD(H(A1), unq(nonce-value):nc-value:unq(cnonce-value):unq(qop-value):H(A2))
Si la directiva “qop” no está presente (esta construcción es para compatibilidad con RFC 2069):
request-digest = KD(H(A1), unq(nonce-value):H(A2))
Consulte a continuación las definiciones de A1 y A2.
3.2.2 A1
Si el valor de la directiva "algoritmo" es "MD5" o no está especificado, entonces A1 es:
A1 = unq(username-value):unq(realm-value):passwd
where passwd = < user's password >
Si el valor de la directiva "algoritmo" es "MD5-sess", entonces A1 se calcula solo una vez: en la primera solicitud del cliente después de recibir un desafío WWW-Authenticate del servidor. Utiliza el nonce del servidor de ese desafío y el primer valor del nonce del cliente para construir A1 de la siguiente manera:
A1 = H(unq(username-value):unq(realm-value):passwd):unq(nonce-value):unq(cnonce-value)
Esto crea una 'clave de sesión' para la autenticación de solicitudes y respuestas posteriores que es diferente para cada "sesión de autenticación", limitando así la cantidad de material codificado con cualquier clave. (Nota: consulte más información sobre la sesión de autenticación en la sección 3.3.) Debido a que el servidor solo necesita usar el hash de las credenciales del usuario para crear el valor A1, esta construcción podría usarse junto con un servicio de autenticación de terceros para que el servidor web no necesitaría el valor de contraseña real. La especificación de dicho protocolo está más allá del alcance de esta especificación.
3.2.3 A2
Si el valor de la directiva "qop" es "auth" o no está especificado, entonces A2 es:
A2 = Method:digest-uri-value
Si el valor "qop" es "auth-int", entonces A2 es:
A2 = Method:digest-uri-value:H(entity-body)
4.Ejemplos
También utilizamos el ejemplo anterior para realizar el procesamiento del algoritmo. algorithm
Si no se asigna ningún valor, es el valor predeterminado MD5
. Se sigue utilizando el nombre de usuario Mufasa
y la contraseña 123456
:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Digest
realm="[email protected]",
qop="auth",
nonce="7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v",
opaque="FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS"
respuesta:
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"
Algoritmo completo, aquí debemos prestar mucha atención a si hay comillas dobles:
// 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);