¿BCrypt es un buen algoritmo de hash para usar en C #? ¿Dónde puedo encontrarlo? [cerrado]

129

He leído que al descifrar una contraseña, muchos programadores recomiendan usar el algoritmo BCrypt.

Estoy programando en C # y me pregunto si alguien sabe de una buena implementación para BCrypt. Encontré esta página , pero realmente no sé si es falsa o no.

¿Qué debo tener en cuenta al elegir un esquema de hash de contraseña? ¿BCrypt es una implementación 'buena'?

Svish
fuente

Respuestas:

148

Primero, algunos términos que son importantes:

Hashing : el acto de tomar una cadena y producir una secuencia de caracteres que no se puede revertir a la cadena original.

Cifrado simétrico : (generalmente conocido como 'cifrado'): el acto de tomar una cadena y producir una secuencia de caracteres que se pueden descifrar en la cadena original mediante el uso de la misma clave de cifrado que la cifró.

Tabla Rainbow : una tabla de búsqueda que contiene todas las variaciones de caracteres hash en un algoritmo de hash específico.

Sal : una cadena aleatoria conocida agregada a la cadena original antes de que se divida en hash.

Para .NET Framework, Bcrypt aún no tiene una implementación de referencia verificada . Esto es importante porque no hay forma de saber si hay fallas graves en una implementación existente. Puede obtener una implementación de BCrypt para .NET aquí . No sé lo suficiente sobre criptografía para decir si es una implementación buena o mala. La criptografía es un campo muy profundo. No intente construir su propio algoritmo de cifrado . Seriamente.

Si va a implementar su propia seguridad de contraseña (suspiro), debe hacer varias cosas:

  1. Use un algoritmo hash relativamente seguro .
  2. Sale cada contraseña antes de que se mezcle.
  3. Use una sal única y larga para cada contraseña y almacene la sal con la contraseña.
  4. Requerir contraseñas seguras .

Desafortunadamente, incluso si haces todo esto, un hacker determinado aún podría descubrir las contraseñas, solo le tomaría mucho tiempo. Ese es tu principal enemigo: el tiempo .

El algoritmo bcrypt funciona porque se necesitan cinco órdenes de magnitud más para descifrar una contraseña que MD5 ; (y todavía mucho más tiempo que AES o SHA-512). Obliga al pirata informático a dedicar mucho más tiempo a crear una tabla de arcoíris para buscar sus contraseñas, por lo que es mucho menos probable que sus contraseñas estén en peligro de ser pirateadas.

Si está usando sal y hash para sus contraseñas, y cada sal es diferente, entonces un pirata informático potencial tendría que crear una tabla de arco iris para cada variación de sal , solo para tener una tabla de arco iris para una contraseña salada + hash. Eso significa que si tiene 1 millón de usuarios, un hacker debe generar 1 millón de tablas de arcoíris. Si está utilizando la misma sal para cada usuario, entonces el hacker solo tiene que generar 1 tabla de arcoíris para hackear con éxito su sistema.

Si no está usando sus contraseñas, todo lo que un atacante debe hacer es abrir una tabla Rainbow existente para cada implementación (AES, SHA-512, MD5) y ver si una coincide con el hash. Esto ya se ha hecho , un atacante no necesita calcular estas tablas Rainbow .

Incluso con todo esto, debes estar usando buenas prácticas de seguridad . Si pueden usar con éxito otro vector de ataque (XSS, inyección de SQL, CSRF, et al. ) En su sitio, la buena seguridad de la contraseña no importa. Eso suena como una declaración controvertida, pero piénselo: si puedo obtener toda su información de usuario a través de un ataque de inyección SQL, o puedo hacer que sus usuarios me den sus cookies a través de XSS, entonces no importa qué tan buena sea su contraseña la seguridad es .

Otros recursos:

  1. Jeff Atwood: .NET Encryption Simplified (ideal para una descripción general del hashing)
  2. Jeff Atwood: acabo de iniciar sesión como tú
  3. Jeff Atwood: Probablemente esté almacenando contraseñas incorrectamente
  4. Jeff Atwood: Speed ​​Hashing

Nota: Recomiende otros buenos recursos. Debo haber leído una docena de artículos de docenas de autores, pero pocos escriben sobre el tema tan claramente como lo hace Jeff. Edite los artículos a medida que los encuentre.

George Stocker
fuente
quizás agregue a su párrafo de sal que una sal debe ser elegida al azar
Jacco
2
@Jacco Buena llamada, agregó. Aunque eso no es tan importante. Simplemente puede usar la marca de tiempo del inicio de sesión para la sal. La diferencia es que el atacante debe volver a calcular la tabla de arco iris para cada sal. Eso es lo que lo hace difícil, no es que se elija al azar. Hacerlo al azar agregaría otra capa de obstrucción, pero eso es inútil una vez que el atacante puede ver su base de datos (que es el problema que causa toda nuestra angustia en primer lugar).
George Stocker
3
En realidad no, la sal no tiene que ser secreta, la única para cada caso. Como único (como en todo el mundo) no es posible, el azar es la siguiente mejor opción. Además, la marca de tiempo no es una buena sal ya que no hay suficiente entropía.
Jacco
77
Discutiría con su declaración "Si pueden usar con éxito la inyección XSS o SQL, la buena seguridad de la contraseña no importa". Por el contrario, si pueden inyectar XSS o SQL con éxito en su sitio, una buena seguridad de contraseña es aún más importante. La clave aquí es la "defensa en profundidad": debe reforzar la seguridad en la medida de lo posible en cada capa de su aplicación.
jammycakes
2
@jammycakes Absolutamente; mi punto se perdió: no se puede decir simplemente: "¡Eh, hemoshs y sal nuestras contraseñas," estamos bien "!
George Stocker
74

No debe usar BCrypt en .NET. Usted debe utilizar PBKDF2 al igual que con la implementación marco construido en .NET. Es la única implementación de verificación criptográfica disponible de forma gratuita en .NET, además de ser el algoritmo recomendado por NIST .

StackId usó anteriormente BCrypt y se mudó a PBKDF2 por esta misma razón:

Para aquellos curiosos, estamos contraseñas hash con PBKDF2. El código correspondiente está aquí ( http://code.google.com/p/stackid/source/browse/OpenIdProvider/Current.cs#1135 ), a través de algunas capas de indirección. En una iteración anterior, estábamos usando BCrypt; pero se trasladó a PBKDF2 ya que está integrado en el marco .NET, mientras que BCrypt requeriría que verifiquemos una implementación (no es una tarea pequeña).

Kevin Montrose, 27 de mayo de 2011

(Enlace actualizado en GitHub)

Editar: El significado de verificado en términos criptográficos parece no entenderse fácilmente, una implementación verificada significa que se ha demostrado criptográficamente que se implementa sin errores. El costo de esto puede llegar fácilmente a $ 20,000 o más. Recuerdo esto cuando estaba investigando sobre OpenSSL y leí donde decían que no habían completado todo el proceso de verificación, pero si es necesario verificarlo completamente, pueden indicarle el camino correcto para ello y mencionar los costos asociados. Ciertos requisitos gubernamentales incluyen mandatos para algoritmos de cifrado verificados.

Las implementaciones de bcrypt en .NET no se han verificado. Al usar una implementación de cifrado no verificada, no puede estar absolutamente seguro de que no haya fallas intencionales maliciosas, como permitir una puerta trasera a lo que es cifrado o fallas de implementación no intencionales que resultan en datos criptográficamente inseguros.

Edición de 2014: para cualquiera que haya cuestionado la necesidad de utilizar algoritmos criptográficos verificados, observe la devastación provocada por el hack desangrado explotado en OpenSSL. Ese es el costo de usar una implementación no verificada. Es seguro ... hasta que descubra que cualquier persona puede leer todo el contenido de la memoria de su servidor.

El autor del cambio que introdujo Heartbleed, Robin Seggelmann, declaró que "omitió validar una variable que contenía una longitud" y negó cualquier intención de presentar una implementación defectuosa. Tras la divulgación de Heartbleed, Seggelmann sugirió centrarse en el segundo aspecto, afirmando que OpenSSL no es revisado por suficientes personas.

Esta es la definición de una implementación no verificada. Incluso el defecto más pequeño puede provocar la invalidez de toda la seguridad.

Edición de 2015: Se eliminó el lenguaje basado en recomendaciones y se reemplazó con absolutos. Comentario original integrado de Kevin Montrose para la posteridad.

Chris Marisic
fuente
25
Para citar el comentario vinculado: "[nos] mudamos a PBKDF2 ya que está integrado en el marco .NET, mientras que BCrypt requeriría que verifiquemos una implementación". Tenga en cuenta que el comentario no dice que el algoritmo es mejor, solo que SE Dev Team considera que la implementación de PBKDF2 incorporada es más confiable que una biblioteca externa (que es, en última instancia, una llamada de juicio).
Piskvor salió del edificio el
3
@Piskvor Actualicé mi respuesta. Esto no se trata de lo que el equipo de SO considera seguro, sino de un juicio entre inherentemente seguro o con suerte seguro. Lo último cuando se trata de criptografía es inaceptable.
Chris Marisic
66
Me pregunto cómo SO migró todas las contraseñas hash de bcrypt a los nuevos hashes. ¿No necesitarían las contraseñas sin procesar para hacer hash usando el nuevo algoritmo?
Dharmendar Kumar 'DK'
8
@DK Ni siquiera creo que tenga que pedirles que restablezcan sus contraseñas. En el próximo inicio de sesión (donde proporcionan su contraseña de texto sin formato), puede hacerlo, creo.
Matt Kocaj
12
Este es un mal consejo y me sorprende que tenga tantos votos a favor. Verificar una implementación de BCrypt en un lenguaje administrado es mucho, mucho más trivial que verificar algo como una implementación completa de SSL en C. Heartbleed es completamente irrelevante; sería mejor mencionar algo como problemas de coerción de tipo PHP con comprobaciones de igualdad hash. Además, aunque en gran medida es adecuado en un sentido práctico, PBKDF2 es un KDF, no un algoritmo de hash de contraseña, mientras que BCrypt es más adecuado. De todos modos, tendría mucho más sentido usar Argon2 en estos días de todos modos, para lo cual hay una biblioteca de C # bien probada
Polynomial