El protocolo de contraseña remota segura ( SRP ) es un protocolo de intercambio de claves autenticado con contraseña aumentada (PAKE), diseñado específicamente para evitar las patentes existentes. [1]
Como todos los protocolos PAKE, un fisgón o un intermediario no puede obtener suficiente información para poder adivinar por fuerza bruta una contraseña o aplicar un ataque de diccionario sin más interacciones con las partes para cada adivinación. Además, al ser un protocolo PAKE aumentado, el servidor no almacena datos equivalentes a contraseñas. [2] Esto significa que un atacante que roba los datos del servidor no puede hacerse pasar por el cliente a menos que primero realice una búsqueda por fuerza bruta de la contraseña.
En términos sencillos, durante la autenticación SRP (o cualquier otro protocolo PAKE), una parte (el "cliente" o "usuario") demuestra a otra parte (el "servidor") que conocen la contraseña, sin enviar la contraseña en sí ni otra información de la que se pueda derivar la contraseña. La contraseña nunca sale del cliente y el servidor la desconoce.
Además, el servidor también necesita conocer la contraseña (pero no la contraseña en sí) para iniciar la conexión segura. Esto significa que el servidor también se autentica ante el cliente, lo que evita el phishing sin depender de que el usuario analice URL complejas.
Descripción general
El protocolo SRP tiene una serie de propiedades deseables: permite a un usuario autenticarse en un servidor, es resistente a los ataques de diccionario montados por un fisgón y no requiere un tercero de confianza . Transmite efectivamente una prueba de contraseña de conocimiento cero del usuario al servidor. En la revisión 6 del protocolo, solo se puede adivinar una contraseña por intento de conexión. Una de las propiedades interesantes del protocolo es que incluso si uno o dos de los primitivos criptográficos que utiliza son atacados, sigue siendo seguro. El protocolo SRP se ha revisado varias veces y actualmente se encuentra en la revisión 6a.
El protocolo SRP crea una gran clave privada compartida entre las dos partes de una manera similar al intercambio de claves Diffie-Hellman basado en que el lado del cliente tiene la contraseña de usuario y el lado del servidor tiene un verificador criptográfico derivado de la contraseña. La clave pública compartida se deriva de dos números aleatorios, uno generado por el cliente y el otro generado por el servidor, que son exclusivos del intento de inicio de sesión. En los casos en los que se requieren comunicaciones cifradas y autenticación, el protocolo SRP es más seguro que el protocolo SSH alternativo y más rápido que utilizar el intercambio de claves Diffie-Hellman con mensajes firmados. También es independiente de terceros, a diferencia de Kerberos . El protocolo SRP, versión 3 se describe en RFC 2945. SRP versión 6 también se utiliza para autenticación de contraseña segura en SSL / TLS [5] (en TLS-SRP ) y otros estándares como EAP [6] y SAML , y está siendo estandarizado en IEEE P1363 e ISO / IEC 11770-4.
Protocolo
La siguiente notación se utiliza en esta descripción del protocolo, versión 6:
- q y N = 2 q + 1 se eligen de manera que ambos sean primos (lo que hace que q sea un primo de Sophie Germain y N un primo seguro ). N debe ser lo suficientemente grande para que no sea factible calcular logaritmos discretos módulo N.
- Toda la aritmética se realiza en el anillo de números enteros módulo N ,. Esto significa que debajo de g x debe leerse como g x mod N
- g es un generador del grupo multiplicativo.
- H () es una función hash ; por ejemplo, SHA-256.
- k es un parámetro derivado por ambos lados; en SRP-6, k = 3, mientras que en SRP-6a se deriva de N y g : k = H ( N , g ). Se utiliza para evitar una suposición de 2 por 1 cuando un atacante activo se hace pasar por el servidor. [7] [8]
- s es una sal pequeña .
- Yo es un nombre de usuario identificativo.
- p es la contraseña del usuario.
- v es el verificador de contraseñas del host, v = g x donde, como mínimo, x = H ( s , p ). Como x solo se calcula en el cliente, es libre de elegir un algoritmo más fuerte. Una implementación podría optar por usar x = H ( s | I | p ) sin afectar los pasos requeridos por el host. El estándar RFC2945 define x = H ( s | H ( I | ":" | p )) . El uso de I dentro de x evita que un servidor malintencionado pueda saber si dos usuarios comparten la misma contraseña .
- A y B son claves efímeras aleatorias de una sola vez del usuario y del host respectivamente.
- | (tubería) denota concatenación.
Todas las demás variables se definen en función de estas.
Primero, para establecer una contraseña p con el servidor Steve, la cliente Carol elige una pequeña sal aleatoria s , y calcula x = H ( s , p ), v = g x . Tiendas de Steve v y s , indexados por que , como la contraseña de Carol verificador y la sal. Carol no debe compartir x con nadie y debe borrarlo de manera segura en este paso, porque es equivalente a la contraseña de texto sin formato p . Este paso se completa antes de que el sistema se utilice como parte del registro de usuario con Steve. Tenga en cuenta que la sal s es compartido e intercambiaron para negociar una clave de sesión más tarde por lo que el valor podría ser elegido por ambos lados, pero es realizado por Carol para que pueda registrarse I , s y v en una única solicitud de registro. La transmisión y autenticación de la solicitud de registro no está cubierta en SRP.
Luego, para realizar una prueba de contraseña en una fecha posterior, se produce el siguiente protocolo de intercambio:
- Carol → Steve: genera un valor aleatorio a ; enviar I y A = g a
- Steve → Carol: generar valor aleatorio b ; enviar s y B = kv + g b
- Ambos: u = H ( A , B )
- Carol: S Carol = ( B - kg x ) ( a + ux ) = ( kv + g b - kg x ) ( a + ux ) = ( kg x - kg x + g b ) (a + ux) = ( g b ) ( a + ux )
- Carol: K Carol = H ( S Carol )
- Steve: S Steve = ( Av u ) b = ( g a v u ) b = [ g a ( g x ) u ] b = ( g a + ux ) b = ( g b ) (a + ux)
- Steve: K Steve = H ( S Steve ) = K Carol
Ahora las dos partes tienen una clave de sesión K compartida y sólida . Para completar la autenticación, deben demostrarse mutuamente que sus claves coinciden. Una forma posible es la siguiente:
- Carol → Steve: M 1 = H [ H ( N ) XOR H ( g ) | H ( I ) | s | A | B | K Carol ] . Steve verifica M 1 .
- Steve → Carol: M 2 = H ( A | M 1 | K Steve ) . Carol verifica M 2 .
Este método requiere adivinar más del estado compartido para tener éxito en la suplantación que solo la clave. Si bien la mayor parte del estado adicional es público, la información privada podría agregarse de manera segura a las entradas de la función hash, como la clave privada del servidor. [ aclaración necesaria ]
Alternativamente, en una prueba de solo contraseña, el cálculo de K se puede omitir y la S compartida se puede probar con:
- Carol → Steve: M 1 = H ( A | B | S Carol ) . Steve verifica M 1 .
- Steve → Carol: M 2 = H ( A | M 1 | S Steve ) . Carol verifica M 2 .
Cuando se usa SRP para negociar una clave compartida K que se usará inmediatamente después de la negociación, se pueden omitir los pasos de verificación de M 1 y M 2 . El servidor rechazará la primera solicitud del cliente que no puede descifrar. Saltarse los pasos de verificación puede ser peligroso. [ cita requerida ]
Las dos partes también emplean las siguientes salvaguardas:
- Carol abortará si recibe B = 0 (mod N ) o u = 0.
- Steve abortará si recibe A (mod N ) = 0.
- Carol debe mostrar su prueba de K (o S ) primero. Si Steve detecta que la prueba de Carol es incorrecta, debe abortar sin mostrar su propia prueba de K (o S )
Código de ejemplo en Python
#! / usr / bin / env ipython3 -m IPython.lib.demo - -C "" " Un ejemplo de autenticación SRPADVERTENCIA: No lo utilice con fines criptográficos reales más allá de las pruebas. ADVERTENCIA: Este código a continuación no incluye salvaguardas importantes. No comprueba que A, B y U no sean cero.basado en http://srp.stanford.edu/design.html "" " import hashlib import random# Nota: str se convierte tal cual, str ([1,2,3,4]) se convertirá a "[1,2,3,4]" def H ( * args ) -> int : "" "A uno- way función hash. "" " a = ": " . join ( str ( a ) para a en args ) return int ( hashlib . sha256 ( a . encode ( "utf-8" )) . hexdigest (), 16 )def cryptrand ( n : int = 1024 ): devuelve aleatorio . SystemRandom () . getrandbits ( n ) % N# Un primo seguro grande (N = 2q + 1, donde q es primo) # Toda la aritmética se realiza módulo N # (generado usando "openssl dhparam -text 1024") N = "" "00: c0: 37: c3: 75 : 88: b4: 32: 98: 87: e6: 1c: 2d: a3: 32: 4b: 1b: a4: b8: 1a: 63: f9: 74: 8f: ed: 2d: 8a: 41: 0c: 2f : c2: 1b: 12: 32: f0: d3: bf: a0: 24: 27: 6c: fd: 88: 44: 81: 97: aa: e4: 86: a6: 3b: fc: a7: b8: bf : 77: 54: df: b3: 27: c7: 20: 1f: 6f: d1: 7f: d7: fd: 74: 15: 8b: d3: 1c: e7: 72: c9: f5: f8: ab: 58 : 45: 48: a9: 9a: 75: 9b: 5a: 2c: 05: 32: 16: 2b: 7b: 62: 18: e8: f1: 42: bc: e2: c3: 0d: 77: 84: 68 : 9a: 48: 3e: 09: 5e: 70: 16: 18: 43: 79: 13: a8: c3: 9c: 3d: d0: d4: ca: 3c: 50: 0b: 88: 5f: e3 "" " N = int ( "" . join ( N . división ()) . sustituir ( ":" , "" ), 16 ) g = 2 # Un generador de módulo Nk = H ( N , g ) # Parámetro multiplicador (k = 3 en SRP-6 heredado)F = '# 0x' # Especificador de formatoprint ( "#. H, N, gyk son conocidos de antemano por el cliente y el servidor:" ) print ( f ' { H =} \ n { N =: { F }} \ n { g =: { F }} \ n { k =: { F }} ' )print ( " \ n 0. el servidor almacena (I, s, v) en su base de datos de contraseñas" )# El servidor debe generar primero el verificador de contraseñas I = "persona" # Nombre de usuario p = "contraseña1234" # Contraseña s = cryptrand ( 64 ) # Salt para el usuario x = H ( s , I , p ) # Clave privada v = pow ( g , x , N ) # Verificador de contraseñaimprimir ( f ' { I =} \ n { p =} \ n { s =: { F }} \ n { x =: { F }} \ n { v =: { F }} ' )# --- detener --- print ( " \ n 1. el cliente envía el nombre de usuario I y el valor público efímero A al servidor" ) a = cryptrand () A = pow ( g , a , N ) print ( f " { I =} \ n { A =: { F }} " ) # cliente-> servidor (I, A)# --- detener --- print ( " \ n 2. el servidor envía los salt s del usuario y el valor efímero público B al cliente" ) b = cryptrand () B = ( k * v + pow ( g , b , N )) % N print ( f " { s =: { F }} \ n { B =: { F }} " ) # servidor-> cliente (s, B)# --- detener --- print ( " \ n 3. el cliente y el servidor calculan el parámetro de codificación aleatoria" ) u = H ( A , B ) # Parámetro de codificación aleatoria print ( f " { u =: { F }} " )# --- detener --- print ( " \ n 4. el cliente calcula la clave de sesión" ) x = H ( s , I , p ) S_c = pow ( B - k * pow ( g , x , N ), a + u * x , N ) K_c = H ( S_c ) print ( f " { S_c =: { F }} \ n { K_c =: { F }} " )# --- detener --- print ( " \ n 5. el servidor calcula la clave de sesión" ) S_s = pow ( A * pow ( v , u , N ), b , N ) K_s = H ( S_s ) print ( f " { S_s =: { F }} \ n { K_s =: { F }} " )# --- detener --- print ( " \ n 6. el cliente envía prueba de clave de sesión al servidor" ) M_c = H ( H ( N ) ^ H ( g ), H ( I ), s , A , B , K_c ) print ( f " { M_c =: { F }} " ) # cliente-> servidor (M_c); el servidor verifica M_c# --- detener --- print ( " \ n 7. el servidor envía prueba de clave de sesión al cliente" ) M_s = H ( A , M_c , K_s ) print ( f " { M_s =: { F }} " ) # servidor-> cliente (M_s); el cliente verifica M_s
Implementaciones
- Variables SRP-6 Una biblioteca Java de primitivas criptográficas necesarias para implementar el protocolo SRP-6.
- OpenSSL versión 1.0.1 o posterior.
- Botan (la biblioteca de cifrado C ++) contiene una implementación de SRP-6a
- TLS-SRP es un conjunto de conjuntos de cifrado para la seguridad de la capa de transporte que utiliza SRP.
- srp-client SRP-6a implementación en JavaScript (compatible con RFC 5054), código abierto, licencia Mozilla Public License (MPL).
- La biblioteca de cifrado de JavaScript incluye una implementación de JavaScript del protocolo SRP, de código abierto, con licencia BSD .
- Gnu Crypto proporciona una implementación de Java con licencia de GNU General Public License con la "excepción de biblioteca", que permite su uso como biblioteca junto con software no libre.
- Legion of the Bouncy Castle proporciona implementaciones de Java y C # bajo la licencia MIT .
- Nimbus SRP es una biblioteca de Java que proporciona un generador de verificadores, sesiones del lado del cliente y del servidor. Incluye interfaces para claves de contraseña personalizadas, rutinas de mensajes de evidencia de cliente y servidor. Sin dependencias externas. Publicado bajo la licencia Apache 2.0 .
- srplibcpp es una base de implementación de C ++ en MIRACL .
- DragonSRP es una implementación modular de C ++ que actualmente funciona con OpenSSL .
- Json2Ldap proporciona autenticación SRP-6a a los servidores de directorio LDAP .
- Implementación de csrp SRP-6a en C.
- Implementación de Crypt-SRP SRP-6a en Perl .
- Implementación de pysrp SRP-6a en Python (compatible con csrp ).
- Implementación de py3srp SRP-6a en Python3 puro .
- srptools Herramientas para implementar la autenticación de contraseña remota segura (SRP) en Python . Bibliotecas compatibles verificadas .
- El sistema de cuentas de Meteor web framework implementa SRP para la autenticación de contraseña.
- Implementación de srp-rb SRP-6a en Ruby .
- Falkmueller demo SRP-6a implementación del diseño del protocolo SRP de Stanford en JavaScript y PHP bajo la licencia MIT .
- srp-6a-demo Implementación de SRP-6a en PHP y JavaScript .
- Implementación de thinbus-srp-js SRP-6a en JavaScript . Viene con clases Java compatibles que usan Nimbus SRP, una aplicación de demostración que usa Spring Security . También hay una aplicación de demostración que realiza la autenticación en un servidor PHP . Publicado bajo la licencia Apache .
- Stanford JavaScript Crypto Library (SJCL) implementa SRP para el intercambio de claves.
- node-srp es una implementación de cliente y servidor JavaScript (node.js) de SRP.
- SRP6 para la implementación de C # y Java en C # y Java.
- ALOSRPAuth es una implementación de Objective-C de SRP-6a.
- go-srp es una implementación Go de SRP-6a.
- tssrp6a es una implementación TypeScript de SRP-6a.
- La biblioteca Java de criptografía de TheIceNet para desarrollar aplicaciones Spring Boot basadas en criptografía. Implementa SRP-6a. Bajo licencia Apache .
Ver también
- Autenticación de desafío-respuesta
- Acuerdo de clave autenticada con contraseña
- Mecanismo de autenticación de respuesta de desafío salado (SCRAM)
- Intercambio de claves exponencial de contraseña simple
- Prueba de contraseña de conocimiento cero
Referencias
- ^ "¿Qué es SRP?" . Universidad de Stanford .
- ^ Sherman, Alan T .; Lanús, Erin; Liskov, Moisés; Zieglar, Edward; Chang, Richard; Golaszewski, Enis; Wnuk-Fink, Ryan; Bonyadi, Cyrus J .; Yaksetig, Mario (2020), Nigam, Vivek; Ban Kirigin, Tajana; Talcott, Carolyn; Guttman, Joshua (eds.), "Análisis de métodos formales del protocolo de contraseña remota segura" , Lógica, lenguaje y seguridad: ensayos dedicados a Andre Scedrov con motivo de su 65 cumpleaños , Notas de la conferencia en informática, Cham: Springer International Publishing, págs. 103-126, arXiv : 2003.07421 , doi : 10.1007 / 978-3-030-62077-6_9 , ISBN 978-3-030-62077-6, consultado 2020-12-02
- ^ "¿Deberías usar SRP?" .
- ^ "OPAQUE: un protocolo PAKE asimétrico seguro contra ataques previos a la computación" (PDF) .
- ^ Taylor, David; Tom Wu; Nikos Mavrogiannopoulos; Trevor Perrin (noviembre de 2007). "Uso del protocolo de contraseña remota segura (SRP) para la autenticación TLS" . RFC 5054
- ^ Carlson, James; Bernard Aboba; Henry Haverinen (julio de 2001). "Protocolo de autenticación EAP SRP-SHA1" . IETF. Sequía.
- ^ Wu, Tom (29 de octubre de 2002). "SRP-6: Mejoras y perfeccionamientos del Protocolo de contraseña remota segura" .
- ^ "Diseño de protocolo SRP" .
enlaces externos
- Página web oficial
- Licencia SRP —BSD como código abierto.
- US6539479 - Patente SRP (venció el 12 de mayo de 2015 debido a la falta de pago de las tarifas de mantenimiento (según Google Patents). Originalmente, vencerá en julio de 2018)
Páginas del manual
- pppd (8) : Demonio de protocolo punto a punto
- srptool (1) : herramienta de contraseña SRP simple
RFC
- RFC 2944 - Autenticación Telnet: SRP
- RFC 2945 - El sistema de intercambio de claves y autenticación SRP (versión 3)
- RFC 3720 - Interfaz de sistemas informáticos pequeños de Internet (iSCSI)
- RFC 3723 - Protección de protocolos de almacenamiento en bloque a través de IP
- RFC 3669 - Directrices para grupos de trabajo sobre cuestiones de propiedad intelectual
- RFC 5054: uso del protocolo de contraseña remota segura (SRP) para la autenticación TLS
Otros enlaces
- IEEE 1363
- Diapositivas de propiedad intelectual de SRP (diciembre de 2001 - posible desaprobación) Las patentes de EKE mencionadas expiraron en 2011 y 2013.