En criptografía, el mecanismo de autenticación de desafío-respuesta con sal ( SCRAM ) es una familia de mecanismos de autenticación de desafío-respuesta modernos basados en contraseñas que proporcionan autenticación de un usuario a un servidor. Como se especifica para la capa de seguridad y autenticación simple (SASL), se puede utilizar para inicios de sesión basados en contraseñas a servicios como LDAP , HTTP , SMTP , POP3 , IMAP y JMAP ( correo electrónico ), XMPP (chat) o MongoDB y PostgreSQL (bases de datos). Para XMPP, es obligatorio admitirlo. [1]
Alice quiere acceder al servidor de Bob. Necesita demostrar que es quien dice ser. Para resolver este problema de autenticación, Alice y Bob han acordado una contraseña, que Alice conoce y Bob sabe cómo verificar.
Ahora Alice podría enviar su contraseña a Bob a través de una conexión no cifrada en formato de texto sin cifrar, para que él la verifique. Sin embargo, eso haría que la contraseña fuera accesible para Mallory, que está pinchando la línea. Alice y Bob podrían intentar evitar esto cifrando la conexión. Sin embargo, Alice no sabe si el cifrado fue configurado por Bob y no por Mallory mediante un ataque de intermediario . Por lo tanto, Alice envía una versión en hash de su contraseña, como en CRAM-MD5 o DIGEST-MD5 . Como es un hash, Mallory no obtiene la contraseña en sí. Como el hash está acompañado de un desafío, Mallory podría usarlo solo para un proceso de inicio de sesión. Sin embargo, Alice quiere darle cierta información confidencial a Bob y quiere estar segura de que es Bob y no Mallory.
Para resolver esto, Bob se registró en una autoridad de certificación (CA), que firmó su certificado. Alice podía confiar únicamente en ese sistema de firma, pero sabe que tiene debilidades . Para darle una seguridad adicional de que no hay ningún ataque de intermediario, Bob crea una prueba de que conoce la contraseña (o un hash con sal de la misma) e incluye su certificado en esta prueba. Esta inclusión se denomina enlace de canal, ya que el canal de cifrado inferior está "enlazado" al canal de aplicación superior.
Alice tiene entonces una autenticación de Bob, y Bob tiene una autenticación de Alice. En conjunto, tienen autenticación mutua . DIGEST-MD5 ya habilitaba la autenticación mutua, pero a menudo se implementaba incorrectamente. [2] [3]
Cuando Mallory ejecuta un ataque de intermediario y falsifica una firma de CA, puede recuperar un hash de la contraseña, pero no puede hacerse pasar por Alice ni siquiera en una única sesión de inicio de sesión, ya que Alice incluye en su hash la clave de cifrado de Mallory, lo que provoca un error de inicio de sesión de Bob. Para realizar un ataque totalmente transparente, Mallory necesitaría saber la contraseña utilizada por Alice o la clave de cifrado secreta de Bob.
Bob ha oído hablar de violaciones de datos de bases de datos de servidores y decidió que no quiere almacenar las contraseñas de sus usuarios en texto sin formato. Ha oído hablar de los esquemas de inicio de sesión CRAM-MD5 y DIGEST-MD5, pero sabe que, para ofrecer estos esquemas de inicio de sesión a sus usuarios, tendría que almacenar contraseñas con un hash débil y sin sal. No le gusta la idea y, por lo tanto, decide exigir las contraseñas en texto sin formato. Luego puede hacer un hash con esquemas de hash seguros como bcrypt , scrypt o PBKDF2 y aplicarles sal como quiera. Sin embargo, Bob y Alice seguirían enfrentándose a los problemas descritos anteriormente. Para resolver este problema, utilizan SCRAM, donde Bob puede almacenar su contraseña en un formato con sal, utilizando PBKDF2. Durante el inicio de sesión, Bob envía a Alice su sal y el recuento de iteraciones del algoritmo PBKDF2, y luego Alice los utiliza para calcular la contraseña con hash que Bob tiene en su base de datos. Todos los cálculos posteriores en SCRAM se basan en este valor que ambos conocen.
Aunque todos los clientes y servidores tienen que soportar el algoritmo hash SHA-1 , SCRAM es, a diferencia de CRAM-MD5 o DIGEST-MD5 , independiente de la función hash subyacente. [4] En su lugar, se pueden utilizar todas las funciones hash definidas por la IANA. [5] Como se mencionó en la sección Motivación, SCRAM utiliza el mecanismo PBKDF2 , que aumenta la resistencia contra ataques de fuerza bruta , cuando se produce una fuga de datos en el servidor. Sea H
la función hash seleccionada, dada por el nombre del algoritmo anunciado por el servidor y elegido por el cliente. 'SCRAM-SHA-1', por ejemplo, utiliza SHA-1 como función hash.
El cliente deriva una clave, o contraseña con sal, a partir de la contraseña, una sal y una serie de iteraciones computacionales de la siguiente manera:
SaltedPassword = H(password, salt, iteration-count) = PBKDF2(HMAC, password, salt, iteration-count, output length of H)
.RFC 5802 nombra cuatro mensajes consecutivos entre el servidor y el cliente:
username
y un nonce de cliente generado aleatoriamente c-nonce
.s-nonce
, y lo agrega al mensaje server-first , que también contiene un salt
utilizado por el servidor para salar el hash de la contraseña del usuario, y un recuento de iteraciones iteration-count
.proof
.verifier
.El cliente y el servidor se demuestran mutuamente que tienen la misma Auth
variable, que consiste en:
Auth = client-first-without-header + , + server-first + , + client-final-without-proof
(concatenado con comas)Más concretamente, esto toma la forma:
= n=username,r=c‑nonce,[extensions,]r=c‑nonce‖s‑nonce,s=salt,i=iteration‑count,[extensions,]c=base64(channel‑flag,[a=authzid],channel‑binding),r=c‑nonce‖s‑nonce[,extensions]
Las pruebas se calculan de la siguiente manera:
ClientKey = HMAC(SaltedPassword, 'Client Key')
ServerKey = HMAC(SaltedPassword, 'Server Key')
ClientProof = p = ClientKey XOR HMAC(H(ClientKey), Auth)
ServerSignature = v = HMAC(ServerKey, Auth)
donde la operación XOR se aplica a cadenas de bytes de la misma longitud, es un hash normal de . y son cadenas textuales.H(ClientKey)
ClientKey
'Client Key'
'Server Key'
El servidor puede autorizar al cliente calculando ClientKey
y ClientProof
luego comparando H(ClientKey)
con el valor almacenado.
El cliente puede autorizar al servidor calculando y comparando ServerSignature
directamente.
El servidor almacena únicamente el nombre de usuario, salt
, iteration-count
, , . El servidor tiene acceso transitorio a la prueba, ya que se recupera del cliente, tras haber sido cifrada con .H(ClientKey)
ServerKey
ClientKey
H(ClientKey)
El cliente sólo necesita el password
.
El término "vinculación de canal " describe la estrategia de prevención de ataques de intermediarios para "vincular" una capa de aplicación , que proporciona autenticación mutua, a una capa inferior (principalmente de cifrado), lo que garantiza que los puntos finales de una conexión sean los mismos en ambas capas. Hay dos direcciones generales para la vinculación de canal: vinculación de canal única y vinculación de canal de punto final . La primera garantiza que se use una conexión específica, la segunda que los puntos finales sean los mismos.
Existen varios tipos de enlaces de canal, donde cada tipo tiene un prefijo único de enlace de canal . [6] Cada tipo de enlace de canal especifica el contenido de los datos de enlace de canal , que proporcionan información única sobre el canal y los puntos finales. Por ejemplo, para el enlace de canal tls-server-end-point , es el certificado TLS del servidor. [7] Un ejemplo de caso de uso de enlace de canal con SCRAM como capa de aplicación, podría ser con Transport Layer Security (TLS) como capa inferior. TLS protege contra escuchas pasivas, ya que la comunicación está cifrada. Sin embargo, si el cliente no autentica al servidor (por ejemplo, verificando el certificado del servidor), esto no evita los ataques de intermediario. Para esto, los puntos finales deben asegurar sus identidades entre sí, lo que puede proporcionar SCRAM.
La variable SCRAM gs2-cbind-flag especifica si el cliente admite o no la vinculación de canales, o piensa que el servidor no admite la vinculación de canales, y c-bind-input contiene gs2-cbind-flag junto con el prefijo único de vinculación de canales y los datos de vinculación de canales en sí.
La vinculación de canales es opcional en SCRAM, y la variable gs2-cbind-flag evita ataques de degradación .
Cuando un servidor admite la vinculación de canales, agrega la secuencia de caracteres '-PLUS' al nombre del algoritmo SCRAM anunciado.