stringtranslate.com

Argón2

Argon2 es una función de derivación de claves que fue seleccionada como ganadora de la Competencia de Hashing de Contraseñas de 2015. [1] [2] Fue diseñada por Alex Biryukov , Daniel Dinu y Dmitry Khovratovich de la Universidad de Luxemburgo . [3] La implementación de referencia de Argon2 se publica bajo una licencia Creative Commons CC0 (es decir, dominio público ) o la Licencia Apache 2.0 , y proporciona tres versiones relacionadas:

Los tres modos permiten la especificación mediante tres parámetros que controlan:

Criptoanálisis

Si bien no existe un criptoanálisis público aplicable a Argon2d, hay dos ataques publicados a la función Argon2i. El primer ataque es aplicable solo a la versión anterior de Argon2i, mientras que el segundo se ha extendido a la versión más reciente (1.3). [5]

El primer ataque muestra que es posible calcular una función Argon2i de un solo paso utilizando entre un cuarto y un quinto del espacio deseado sin penalización de tiempo, y calcular una función Argon2i de múltiples pasos utilizando solo el espacio N / e (≈ N /2.72) sin penalización de tiempo. [6] Según los autores de Argon2, este vector de ataque se corrigió en la versión 1.3. [7]

El segundo ataque muestra que Argon2i puede calcularse mediante un algoritmo que tiene una complejidad O( n 7/4 log( n )) para todas las opciones de parámetros σ (costo de espacio), τ (costo de tiempo) y número de subprocesos tales que n = στ . [8] Los autores de Argon2 afirman que este ataque no es eficiente si Argon2i se utiliza con tres o más pasadas. [7] Sin embargo, Joël Alwen y Jeremiah Blocki mejoraron el ataque y demostraron que para que el ataque falle, Argon2i v1.3 necesita más de 10 pasadas sobre la memoria. [5]

Para abordar estas preocupaciones, RFC9106 recomienda utilizar Argon2id para mitigar en gran medida dichos ataques. [9]

Algoritmo

Fuente: [4]

Función Argon2  Entradas: password ( P ): Bytes (0..2 32 -1)  Contraseña (o mensaje) a ser hasheada salt ( S ): Bytes (8..2 32 -1)  Sal (16 bytes recomendados para hashear contraseñas) parallelism ( p ): Número (1..2 24 -1)  Grado de paralelismo (es decir, número de hilos) tagLength ( T ): Número (4..2 32 -1)  Número deseado de bytes devueltos memorySizeKB ( m ): Número (8p..2 32 -1)  Cantidad de memoria (en kibibytes ) a usar iterations ( t ): Número (1..2 32 -1)  Número de iteraciones a realizar version ( v ): Número (0x13) La versión actual es 0x13 (19 decimal) key ( K ): Bytes (0..2 32 -1)  Clave opcional (Errata: PDF dice 0..32 bytes, RFC dice 0..2 32 bytes) associateData ( X ): Bytes (0..2 32 -1)  Datos adicionales arbitrarios opcionales hashType ( y ): Número (0=Argon2d, 1=Argon2i, 2=Argon2id)  Salida: etiqueta: Bytes (tagLength) Los bytes generados resultantes, tagLength bytes de longitud     Generar bloque inicial de 64 bytes H 0 . Todos los parámetros de entrada se concatenan y se introducen como fuente de entropía adicional. Erratas: RFC dice que H 0 es de 64 bits; PDF dice que H 0 es de 64 bytes. Erratas: RFC dice que el hash es H^, el PDF dice que es ℋ (pero no documenta qué es ℋ). En realidad es Blake2b. A los elementos de longitud variable se les antepone su longitud como números enteros little-endian de 32 bits. buffer ← paralelismo ∥ tagLength ∥ memorySizeKB ∥ iteraciones ∥ versión ∥ hashType ∥ Longitud(contraseña) ∥ Contraseña ∥ Longitud(sal) ∥ sal ∥ Longitud(clave) ∥ clave ∥ Longitud(datos asociados) ∥ datos asociados H 0 ← Blake2b(buffer, 64) //el tamaño de hash predeterminado de Blake2b es de 64 bytes Calcular el número de bloques de 1 KB redondeando memorySizeKB al múltiplo más cercano de 4*paralelismo kibibytes blockCount ← Piso(memoriaTamañoKB, 4*paralelismo) Asignar una matriz bidimensional de bloques de 1 KiB (paralelismo filas x columnCount columnas) columnCount ← blockCount / parallelism; //En el RFC, columnCount se conoce como q Calcular el primer y segundo bloque (es decir, columna cero y uno) de cada carril (es decir, fila)  para i ← 0 a paralelismo-1 hacer  para cada fila B i [0] ← Hash(H 0 ∥ 0 ∥ i, 1024) //Generar un resumen de 1024 bytes B i [1] ← Hash(H 0 ∥ 1 ∥ i, 1024) //Generar un resumen de 1024 bytes Calcular las columnas restantes de cada carril  para i ← 0 a paralelismo-1 hacer  //para cada fila  para j ← 2 a columnCount-1 hacer  //para cada columna subsiguiente  //los índices i' y j' dependen de si es Argon2i, Argon2d o Argon2id (Ver sección 3.4) i′, j′ ← GetBlockIndexes(i, j) //la función GetBlockIndexes no está definida B i [j] = G(B i [j-1], B i′ [j′]) //la función hash G no está definida Pases posteriores cuando iteraciones > 1  para nIteration ← 2 a iteraciones hacer  para i ← 0 a paralelismo-1 hacer  para cada fila  para j ← 0 a columnCount-1 hacer  //para cada columna subsiguiente  //Los índices i' y j' dependen de si es Argon2i, Argon2d o Argon2id (consulte la sección 3.4) i′, j′ ← ObtenerÍndicesDeBloque(i, j) si j == 0 entonces B i [0] = B i [0] xor G(B i [columnCount-1], B i′ [j′]) de lo contrario B i [j] = B i [j] xor G(B i [j-1], B i′ [j′]) Calcular el bloque final C como el XOR de la última columna de cada fila C ← B 0 [columnCount-1] para i ← 1 hasta paralelismo-1 hacer C ← C xor B i [columnCount-1] Calcular la etiqueta de salida  que devuelve Hash(C, tagLength)

Función hash de longitud variable

Argon2 utiliza una función hash capaz de generar resúmenes de hasta 232 bytes de longitud. Esta función hash está integrada internamente en Blake2 .

Función Hash(message, digestSize)  Entradas: message: Bytes (0..2 32 -1)  Mensaje a codificar digestSize: Entero (1..2 32 )  Número deseado de bytes a devolver  Salida: digest: Bytes (digestSize) Los bytes generados resultantes, digestSize en bytes de longitud   Hash es una función hash de longitud variable, creada con Blake2b, capaz de generar resume hasta 2 32 bytes. Si el digestSize solicitado es de 64 bytes o menos, entonces usamos Blake2b directamente  if (digestSize <= 64) then  return Blake2b(digestSize ∥ message, digestSize) //concatena el digestSize little endian de 32 bits con los bytes del mensaje Para hashes deseados de más de 64 bytes (por ejemplo, 1024 bytes para bloques Argon2), Usamos Blake2b para generar el doble de bloques de 64 bytes necesarios, y luego solo use 32 bytes de cada bloque Calcular la cantidad de bloques completos (sabiendo que solo vamos a utilizar 32 bytes de cada uno) r ← Ceil(digestSize/32)-2; Generar r bloques completos.  El bloque inicial se genera a partir del mensaje V 1 ← Blake2b(digestSize ∥ message, 64); Los bloques subsiguientes se generan a partir de los bloques anteriores  para i ← 2 hasta r, hacer V i ← Blake2b(V i-1 , 64) Generar el bloque final (posiblemente parcial) partialBytesNeeded ← tamañoDigesto – 32*r; V r+1 ← Blake2b(V r , bytes parciales necesarios) Concatenar los primeros 32 bytes de cada bloque V i (excepto el último bloque posiblemente parcial, que tomamos completo)  Sea A i los 32 bytes inferiores del bloque V i y  devuelva A 1 ∥ A 2 ∥ ... ∥ A r ∥ V r+1

Parámetros mínimos recomendados

A partir de mayo de 2023, la hoja de trucos de almacenamiento de contraseñas de OWASP recomienda que las personas "utilicen Argon2id con una configuración mínima de 19 MiB de memoria, un recuento de iteraciones de 2 y 1 grado de paralelismo". [10]

OWASP recomienda que se prefiera Argon2id sobre Argon2d y Argon2i porque proporciona una resistencia equilibrada tanto a los ataques basados ​​en GPU como a los ataques de canal lateral. [10]

OWASP señala además que las siguientes opciones de Argon2id proporcionan una fuerza criptográfica equivalente y simplemente intercambian el uso de memoria por la carga de trabajo computacional: [10]

Referencias

  1. ^ "Concurso de hash de contraseñas"
  2. ^ Jos Wetzels (8 de febrero de 2016). "Ábrete Sésamo: La competencia de hash de contraseñas y Argon2". arXiv : 1602.03097 [cs.CR].
  3. ^ Argon2: la función de memoria difícil para el hash de contraseñas y otras aplicaciones, Alex Biryukov, et al, 1 de octubre de 2015
  4. ^ ab Biryukov, Alex; Dinu, Daniel; Khovratovich, Dmitry; Josefsson, Simon (septiembre de 2021). "Función de memoria de Argon2 para aplicaciones de hash de contraseñas y prueba de trabajo" . Consultado el 9 de septiembre de 2021 .
  5. ^ por Joël Alwen; Jeremiah Blocki (5 de agosto de 2016). Hacia ataques prácticos a Argon2i y Balloon Hashing (PDF) (Informe).
  6. ^ Henry; Corrigan-Gibbs; Dan Boneh; Stuart Schechter (14 de enero de 2016). Hashing de globo: funciones hash demostrablemente difíciles de manejar con patrones de acceso independientes de los datos (PDF) (informe).
  7. ^ ab "[Cfrg] Argon2 v.1.3". www.ietf.org . Consultado el 30 de octubre de 2016 .
  8. ^ Joël Alwen; Jeremiah Blocki (19 de febrero de 2016). Computación eficiente de funciones de memoria independientes de los datos (PDF) (informe).
  9. ^ "Recomendaciones". Función de memoria de Argon2 para aplicaciones de hash de contraseñas y prueba de trabajo. IETF . Septiembre de 2021. sec. 7.4. doi : 10.17487/RFC9106 . RFC 9106 . Consultado el 12 de julio de 2023 .
  10. ^ abc "Hoja de referencia para el almacenamiento de contraseñas". Serie de hojas de referencia de OWASP . OWASP . Consultado el 17 de mayo de 2023 .

Enlaces externos