De vez en cuando escucho el consejo "Use bcrypt para almacenar contraseñas en PHP, reglas de bcrypt".
Pero que es bcrypt
? PHP no ofrece ninguna de esas funciones, Wikipedia balbucea sobre una utilidad de cifrado de archivos y las búsquedas en la Web solo revelan algunas implementaciones de Blowfish en diferentes idiomas. Ahora Blowfish también está disponible en PHP a través de mcrypt
, pero ¿cómo ayuda eso a almacenar contraseñas? Blowfish es un cifrado de propósito general, funciona de dos maneras. Si se puede cifrar, se puede descifrar. Las contraseñas necesitan una función de hashing unidireccional.
¿Cuál es la explicación?
bcrypt
es un algoritmo de hash unidireccional versus un esquema de cifrado en mi respuesta . Existe todo este concepto erróneo quebcrypt
es solo Blowfish cuando, de hecho, tiene una programación de teclas totalmente diferente que garantiza que el texto sin formato no se pueda recuperar del texto de cifrado sin conocer el estado inicial del cifrado (sal, rondas, clave).Respuestas:
bcrypt
es un algoritmo de hash que es escalable con hardware (a través de un número configurable de rondas). Su lentitud y múltiples rondas aseguran que un atacante debe implementar fondos y hardware masivos para poder descifrar sus contraseñas. Agregue a eso sales por contraseña (bcrypt
REQUIERE sales) y puede estar seguro de que un ataque es prácticamente inviable sin una cantidad ridícula de fondos o hardware.bcrypt
usa el algoritmo Eksblowfish para hacer hash de contraseñas. Si bien la fase de cifrado de Eksblowfish y Blowfish es exactamente la misma, la fase de programación clave de Eksblowfish garantiza que cualquier estado posterior dependa tanto de la sal como de la clave (contraseña del usuario), y ningún estado puede calcularse previamente sin el conocimiento de ambos. Debido a esta diferencia clave,bcrypt
es un algoritmo de hashing unidireccional. No puede recuperar la contraseña de texto plano sin conocer la sal, las rondas y la clave (contraseña). [ Fuente ]Cómo usar bcrypt:
Usando PHP> = 5.5-DEV
Las funciones de hash de contraseña ahora se han integrado directamente en PHP> = 5.5 . Ahora puede usar
password_hash()
para crear unbcrypt
hash de cualquier contraseña:Para verificar una contraseña proporcionada por el usuario contra un hash existente, puede usar la
password_verify()
siguiente:Usando PHP> = 5.3.7, <5.5-DEV (también RedHat PHP> = 5.3.3)
Hay una biblioteca de compatibilidad en GitHub creada basada en el código fuente de las funciones anteriores escritas originalmente en C, que proporciona la misma funcionalidad. Una vez que se instala la biblioteca de compatibilidad, el uso es el mismo que el anterior (menos la notación de matriz abreviada si todavía está en la rama 5.3.x).
Usando PHP <5.3.7 (DEPRECATED)
Puede usar la
crypt()
función para generar hash de bcrypt de cadenas de entrada. Esta clase puede generar sales automáticamente y verificar hashes existentes contra una entrada. Si está utilizando una versión de PHP superior o igual a 5.3.7, se recomienda encarecidamente que utilice la función integrada o la biblioteca de compatibilidad . Esta alternativa se proporciona solo para fines históricos.Puedes usar este código así:
Alternativamente, también puede usar el Framework PHP Hashing Portable .
fuente
mt_rand()
también se siembra usando la hora actual y la ID del proceso actual. Por favor verGENERATE_SEED()
en/ext/standard/php_rand.h
.crypt()
es revisado por pares y verificado luego. El código anterior llama a PHPcrypt()
, que llama a lacrypt()
función POSIX . Todo el código anterior hace más es generar una sal aleatoria (que no tiene que ser criptográficamente segura, la sal no se considera un secreto) antes de llamarcrypt()
. Tal vez deberías investigar un poco antes de llamar al lobo.crypt()
) está sujeto a una vulnerabilidad de seguridad anterior a la 5.3.7 y es (muy levemente) ineficiente posterior a la 5.3.7: aquí se pueden encontrar detalles del problema relevante . Tenga en cuenta también que la nueva API de hashing de contraseña ( compatibilidad con versiones anteriores ) es ahora el método preferido para implementar el hash de contraseña de bcrypt en su aplicación.Entonces, ¿quieres usar bcrypt? ¡Increíble! Sin embargo, al igual que otras áreas de la criptografía, no debería hacerlo usted mismo. Si necesita preocuparse por algo como administrar claves, almacenar sales o generar números aleatorios, lo está haciendo mal.
La razón es simple: es tan trivialmente fácil fastidiar bcrypt . De hecho, si observa casi todos los códigos de esta página, notará que está violando al menos uno de estos problemas comunes.
Acéptalo, la criptografía es difícil.
Déjalo para los expertos. Déjelo a las personas cuyo trabajo es mantener estas bibliotecas. Si necesita tomar una decisión, lo está haciendo mal.
En cambio, solo usa una biblioteca. Existen varios según sus requisitos.
Bibliotecas
Aquí hay un desglose de algunas de las API más comunes.
PHP 5.5 API - (Disponible para 5.3.7+)
A partir de PHP 5.5, se está introduciendo una nueva API para contraseñas hash. También hay una biblioteca de compatibilidad de shim mantenida (por mí) para 5.3.7+. Esto tiene el beneficio de ser una implementación revisada por pares y fácil de usar.
Realmente, pretende ser extremadamente simple.
Recursos:
Zend \ Crypt \ Password \ Bcrypt (5.3.2+)
Esta es otra API que es similar a la de PHP 5.5 y tiene un propósito similar.
Recursos:
PasswordLib
Este es un enfoque ligeramente diferente para el hashing de contraseñas. En lugar de simplemente admitir bcrypt, PasswordLib admite una gran cantidad de algoritmos de hash. Es principalmente útil en contextos en los que necesita compatibilidad con sistemas heredados y dispares que pueden estar fuera de su control. Es compatible con una gran cantidad de algoritmos de hash. Y es compatible con 5.3.2+
Referencias
PHPASS
Esta es una capa que admite bcrypt, pero también admite un algoritmo bastante fuerte que es útil si no tiene acceso a PHP> = 5.3.2 ... En realidad, admite PHP 3.0+ (aunque no con bcrypt).
Recursos
Nota: ¡No use las alternativas PHPASS que no están alojadas en openwall, son proyectos diferentes!
Sobre BCrypt
Si observa, cada una de estas bibliotecas devuelve una sola cadena. Eso se debe a cómo BCrypt funciona internamente. Y hay MUCHAS respuestas sobre eso. Aquí hay una selección que he escrito, que no copiaré / pegaré aquí, pero enlace a:
md5
contraseñas antiguas a bcryptEnvolver
Hay muchas opciones diferentes. Lo que elijas depende de ti. Sin embargo, recomiendo encarecidamente que utilice una de las bibliotecas anteriores para manejar esto por usted.
Nuevamente, si está usando
crypt()
directamente, probablemente esté haciendo algo mal. Si su código está usandohash()
(omd5()
osha1()
) directamente, casi definitivamente está haciendo algo mal.Solo usa una biblioteca ...
fuente
mt_rand()
tiene un período lo suficientemente alto, pero el valor inicial es de solo 32 bits. Por lo tanto, el usomt_rand()
efectivamente lo limita a solo 32 bits de entropía. Lo que gracias al problema del cumpleaños significa que tienes un 50% de posibilidades de colisión con solo 7k de sales generadas (globalmente). Comobcrypt
acepta 128 bits de sal, es mejor usar una fuente que pueda suministrar los 128 bits ;-). (a 128 bits, 50% de probabilidad de colisión ocurre en 2e19 hashes) ...mt_rand
yuniqid
(y por lo tantolcg_value
yrand
) no son las primeras opciones ...Obtendrá mucha información en Enough With The Rainbow Tables: lo que necesita saber sobre esquemas de contraseña segura o marco de hash de contraseña PHP portátil .
El objetivo es descifrar la contraseña con algo lento, por lo que alguien que obtenga su base de datos de contraseñas morirá tratando de forzarla (una demora de 10 ms para verificar una contraseña no es nada para usted, mucho para alguien que intenta forzarla). Bcrypt es lento y puede usarse con un parámetro para elegir qué tan lento es.
fuente
Puede crear un hash unidireccional con bcrypt utilizando la
crypt()
función de PHP y pasando una sal de Blowfish adecuada. Lo más importante de toda la ecuación es que A) el algoritmo no se ha visto comprometido y B) se salpica correctamente cada contraseña . No use una sal para toda la aplicación; que abre toda su aplicación para atacar desde un solo conjunto de tablas Rainbow.PHP - Función de cripta
fuente
crypt()
función de PHP , que admite varias funciones de hash de contraseña diferentes. Asegúrese de no estar utilizandoCRYPT_STD_DES
oCRYPT_EXT_DES
- cualquiera de los otros tipos compatibles está bien (e incluye bcrypt, bajo el nombreCRYPT_BLOWFISH
).crypt
expone varios hashes de contraseña, con bcrypt correspondiente a laCRYPT_BLOWFISH
constante. Bcrypt es actualmente el algoritmo más fuerte soportado porcrypt
y muchos otros que soporta son bastante débiles.Editar: 2013.01.15 - Si su servidor lo admitirá, use la solución de martinstoeckli en su lugar.
Todos quieren hacer esto más complicado de lo que es. La función crypt () hace la mayor parte del trabajo.
Ejemplo:
Sé que debería ser obvio, pero no uses 'contraseña' como contraseña.
fuente
2y
lugar de2a
.mcrypt_create_iv($size, MCRYPT_DEV_URANDOM)
como fuente de sal.bcrypt
usos personalizados del alfabeto .mcrypt_create_iv(17, MCRYPT_DEV_URANDOM)
,str_replace('+', '.', base64_encode($rawSalt))
,$salt = substr($salt, 0, 22);
La versión 5.5 de PHP tendrá soporte incorporado para BCrypt, las funciones
password_hash()
ypassword_verify()
. En realidad, estos son solo envoltorios alrededor de la funcióncrypt()
, y facilitarán su uso correcto. Se encarga de la generación de una sal aleatoria segura y proporciona buenos valores predeterminados.La forma más fácil de usar estas funciones será:
Este código codificará la contraseña con BCrypt (algoritmo
2y
), genera una sal aleatoria de la fuente aleatoria del sistema operativo y utiliza el parámetro de costo predeterminado (en este momento es 10). La segunda línea verifica si el usuario ingresó la contraseña que coincide con un valor hash ya almacenado.Si desea cambiar el parámetro de costo, puede hacerlo así, aumentando el parámetro de costo en 1, duplicando el tiempo necesario para calcular el valor hash:
A diferencia del
"cost"
parámetro, es mejor omitir"salt"
parámetro, porque la función ya hace todo lo posible para crear una sal criptográficamente segura.Para PHP versión 5.3.7 y posterior, existe un paquete de compatibilidad , del mismo autor que realizó la
password_hash()
función. Para las versiones de PHP 5.3.7 antes no hay apoyo paracrypt()
con2y
el algoritmo Bcrypt segura Unicode. En su lugar2a
, se podría reemplazar con , que es la mejor alternativa para versiones anteriores de PHP.fuente
Pensamiento actual: los hash deben ser los más lentos disponibles, no los más rápidos posibles. Esto suprime la mesa arcoiris ataques de la .
También relacionado, pero con precaución: un atacante nunca debe tener acceso ilimitado a su pantalla de inicio de sesión. Para evitar eso: configure una tabla de seguimiento de direcciones IP que registre cada golpe junto con el URI. Si más de 5 intentos de inicio de sesión provienen de la misma dirección IP en un período de cinco minutos, bloquee con una explicación. Un enfoque secundario es tener un esquema de contraseña de dos niveles, como lo hacen los bancos. Poner un bloqueo por fallas en el segundo pase aumenta la seguridad.
Resumen: ralentice al atacante mediante el uso de funciones hash que consumen mucho tiempo. Además, bloquee demasiados accesos a su inicio de sesión y agregue un segundo nivel de contraseña.
fuente
¡Aquí hay una respuesta actualizada a esta vieja pregunta!
La forma correcta de hash contraseñas en PHP desde 5.5 es con
password_hash()
, y la forma correcta de verificarlas es conpassword_verify()
, y esto sigue siendo cierto en PHP 8.0. Estas funciones usan hash de bcrypt por defecto, pero se han agregado otros algoritmos más fuertes. Puede modificar el factor de trabajo (efectivamente, qué tan "fuerte" es el cifrado) a través depassword_hash
parámetros.Sin embargo, aunque todavía es lo suficientemente fuerte, bcrypt ya no se considera de vanguardia ; Ha llegado un mejor conjunto de algoritmos de hash de contraseña llamado Argon2 , con variantes Argon2i, Argon2d y Argon2id. La diferencia entre ellos (como se describe aquí ):
El soporte de Argon2i se agregó en PHP 7.2, y lo solicita así:
y el soporte Argon2id fue agregado en PHP 7.3:
No se requieren cambios para verificar las contraseñas ya que la cadena hash resultante contiene información sobre qué algoritmo, sal y factores de trabajo se usaron cuando se creó.
Por separado (y de forma algo redundante), libsodium (agregado en PHP 7.2) también proporciona el hash Argon2 a través de las funciones
sodium_crypto_pwhash_str ()
ysodium_crypto_pwhash_str_verify()
, que funcionan de la misma manera que las funciones integradas de PHP. Una posible razón para usarlos es que a veces PHP puede compilarse sin libargon2, lo que hace que los algoritmos Argon2 no estén disponibles para la función password_hash; PHP 7.2 y versiones superiores siempre deben tener libsodium habilitado, pero puede que no sea así, pero al menos hay dos formas de obtener ese algoritmo. Así es como puede crear un hash Argon2id con libsodium (incluso en PHP 7.2, que de lo contrario carece de soporte Argon2id):Tenga en cuenta que no le permite especificar una sal manualmente; Esto es parte del espíritu de libsodium: no permita que los usuarios establezcan parámetros a valores que puedan comprometer la seguridad ; por ejemplo, no hay nada que le impida pasar una cadena de sal vacía a la
password_hash
función de PHP ; ¡libsodium no te deja hacer nada tan tonto!fuente
Para las contraseñas de OAuth 2 :
fuente
Como todos sabemos, el almacenamiento de la contraseña en texto claro en la base de datos no es seguro. El bcrypt es una técnica de contraseña hash. Se utiliza para construir la seguridad de la contraseña. Una de las funciones sorprendentes de bcrypt es que nos salva de los piratas informáticos. Se utiliza para proteger la contraseña de ataques de piratería porque la contraseña se almacena en forma cifrada.
la función password_hash () se usa para crear un nuevo hash de contraseña. Utiliza un algoritmo de hashing fuerte y robusto. La función password_hash () es muy compatible con la función crypt (). Por lo tanto, los hashes de contraseña creados por crypt () se pueden usar con password_hash () y viceversa. Las funciones password_verify () y password_hash () son solo los contenedores alrededor de la función crypt (), y hacen que sea mucho más fácil usarlo con precisión.
SINTAXIS
Los siguientes algoritmos son compatibles actualmente con la función password_hash ():
PASSWORD_DEFAULT PASSWORD_BCRYPT PASSWORD_ARGON2I PASSWORD_ARGON2ID
Parámetros: esta función acepta tres parámetros como se mencionó anteriormente y se describe a continuación:
contraseña : almacena la contraseña del usuario. algo : es la constante del algoritmo de contraseña que se utiliza continuamente mientras se denota el algoritmo que se utilizará cuando se produce el hash de contraseña. opciones : es una matriz asociativa, que contiene las opciones. Si esto se elimina y no incluye, se utilizará una sal aleatoria y se utilizará un costo predeterminado. Valor de retorno : devuelve la contraseña hash en caso de éxito o False en caso de error.
Ejemplo :
Los programas a continuación ilustran la función password_hash () en PHP:
SALIDA
fuente