Como señala @Rook, la mayor parte de las ventajas de hardware especializado como GPU es a través de la paralelización. Un solo núcleo de GPU, por sí mismo, es bastante débil; se sincroniza a una frecuencia inferior a la de la CPU principal y solo computará una operación por ciclo de reloj (en el mejor de los casos, y con una latencia alta). Sin embargo, una GPU incluye cientos de núcleos que bailan simultáneamente.
Ahora, sucede que las funciones de hashing de contraseña habituales son inherentemente secuenciales. Ver, por ejemplo, PBKDF2 : cada fragmento de salida se calcula como el resultado final de una secuencia de U i valores, donde Ui+1 se obtiene al procesar Ui con un PRF (normalmente HMAC). Esto no puede hacerse paralelo. Si desea calcular una única instancia de PBKDF2 en una GPU, entonces usará solo un núcleo en esa GPU, y esto será muy lento. De hecho, un núcleo de GPU típico puede iniciar una instrucción por ciclos de reloj, pero el resultado estará disponible solo diez o veinte ciclos más tarde, por lo que la GPU se utiliza a su máxima potencia solo si tiene miles de tareas para correr en paralelo.
El atacante se beneficia de la GPU porque, por definición, el atacante tiene muchas contraseñas potenciales para probar. Para que pueda usar la computación paralela en toda su potencia; el forzamiento de contraseñas es un problema vergonzosamente paralelo . De hecho, ya que cada núcleo de GPU El defensor , por otro lado, no tiene mucho hashing: solo uno por cliente entrante a la vez. Podríamos imaginar un servidor muy ocupado con, en cualquier momento, cientos de clientes que intentan abrir una sesión, y eso podría ser optimizado con una GPU, pero esto no es muy realista.
Por lo tanto, no hay una implementación lista para usar de un marco de autenticación que descargue el costo de PBKDF2 o bcrypt en una GPU porque no funcionaría. En el contexto de la autenticación de los clientes entrantes (la situación del defensor), el mejor hardware para usar es la CPU, no una GPU.
Dicho esto, esto se debe a que PBKDF2 y bcrypt (y también scrypt y la mayoría de las otras funciones del mismo tipo) son secuenciales. Se podrían diseñar funciones de hashing de contraseñas que se pueden hacer en paralelo. Como ilustración, imagine una función de hashing de contraseña lenta diseñada de esta manera:
- La contraseña es pw , la sal es s .
- Para i = 1 a 10000 , defina V i = PBKDF2 ( pw || i , s ).
- El valor de hash final es SHA-256 ( V 1 || V2 || ... || V10000 ).
En el caso de esa función, la mayor parte del esfuerzo computacional son las diez mil instancias de PBKDF2, que pueden optimizarse con una GPU, incluso si solo tiene una contraseña para el hash.
( Precaución: la función anterior se presenta solo como una ilustración especulativa. ¡No creas que es seguro! Esto no ha sido revisado por muchos criptógrafos entrenados durante varios años. )
Existe una competencia en curso para definir nuevas primitivas de hashing de contraseñas, con el mismo espíritu que los esfuerzos de AES, SHA-3 o eSTREAM. . Si tiene algunas ideas ingeniosas acerca de la definición de una función de hashing de contraseña susceptible de paralelismo, entonces, por supuesto, considere enviar un candidato.