2011-03-10 16 views
9

Creo que estoy perdiendo mis mármoles aquí ... Tengo un problema en mi sitio web donde al azar deja de aceptar inicios de sesión. Ahora he podido rastrearlo a crypt() comportándose de manera muy extraña.PHP crypt() devuelve respuesta incorrecta

En mi base de datos, tengo la versión encriptada de la contraseña de los usuarios, así que digamos Og12345678.

Cuando el usuario inicia sesión, ingresa su contraseña, leo la sal del archivo db y luego cripto lo que ingresaron y compararon; por lo general, esto funciona muy bien.

Así que estoy haciendo crypt ($ enteredPassword, $ saltFromDb) - en este caso, la sal sería Og, por supuesto. Normalmente, para una contraseña de usuario determinada, la cripta funciona bien.

Cuando las cosas van mal (y cuando lo hacen es un cambio permanente hasta que reinicie Apache) encontré que la cripta comienza a devolver una respuesta DIFERENTE para la misma entrada con la misma sal.

Sin embargo, es consistente, es decir, una vez que el sistema se ha equivocado, crypt devuelve una respuesta incorrecta, pero siempre devuelve misma respuesta equivocada. Las repetidas actualizaciones de la página muestran el mismo resultado. La misma sal también se evidencia en el resultado de la cripta también incorrecta, así que no es que la sal se haya perdido en alguna parte.

Si, a continuación, reinicio Apache y vuelvo a ejecutar el script sin ningún cambio, los resultados de crypt regresan a su estado original.

Aprecio que no es el último PHP (5.2.8) pero valoraría cualquier opinión sobre esto, incluyendo si se trata de un error conocido reparado en una versión posterior (actualizar PHP no es una tarea feliz con muchos sitios, algunos de los cuales aún utilizar peculiaridades desafortunadas que todos deben ser reevaluados con cada actualización) - si se trata de un error solucionado conocido, obviamente lo actualizaré todo lo antes posible, más allá de eso, probablemente será más fácil externalizar la cripta externamente ya que solo Úselo en un lugar común para mi sitio.

Cualquier entrada apreciada.

Matt Peddlesden

--- actualización el 11 marzo 2011

corrección al comentario dado previamente sobre el sistema operativo ... - Sistema operativo es 2008 SP1 de 64 bits de Windows Server. Disculpas, debería haber comprobado dos veces en lugar de asumir que pudiera recordar. Machine es un Dell 2950 8gb Ram, procesadores Xeon.

Estoy empezando a pensar en las líneas que sugiere Krtek - cuando el sistema se ha vuelto inestable, si genero nueva cripta() (es decir, un ejemplo muy simple donde establezco una variable en una cadena, lo cripto y luego comparo con la cripta) - todo funciona genial. Cuando reinicio el servidor, nuevamente todo vuelve a los cálculos anteriores. Así que definitivamente me estoy inclinando hacia algo que es cambiando el algoritmo utilizado para calcular el resultado crypt() ... ¿alguna reflexión sobre qué podría causar que esto suceda? Imprimí los valores de CRYPT_STD_DES, etc. y no cambian entre reinicios.

¿Alguien tiene alguna pista sobre lo que podría causar que esto suceda?

Lo que sea que parezca suceder dos veces en un día ayer, más extraño.

Gracias por las respuestas hasta el momento.

--- actualización el 16 marzo 2011

Sólo quería ofrecer otra actualización.

Esto todavía está sucediendo, todavía no hay una mayor comprensión de por qué.

En caso de que alguien se encuentre con esto en el futuro, creo que mi solución va a ser hacer algún truco para sacar todas las ejecuciones crypt() a una aplicación C# externa y dejar de depender de PHP para hacerlos. Algo anda mal en algún lado y en este momento la única solución que puedo ver es eliminarlo por completo de la ecuación.

Por supuesto si todavía sucede, ¡eso también será interesante de saber! :)

Gracias a todos.

+1

creo que es poco probable que este es su problema, pero veo que el consejo en la documentación PHP - http://php.net/manual/en/function.crypt.php: es que debes pasar la contraseña cifrada (salada) como sal. 'if (crypt ($ enteredPassword, $ cryptedPasswordFromDB) == $ cryptedPasswordFromDB) {...}'. El punto parece ser que entonces crypt() puede determinar qué algoritmo de hash está en uso desde $ cryptedPasswordFromDB. De nuevo, dudo que esta sea la causa de su problema, pero podría intentarlo ... –

+1

¿Es posible que una secuencia de comandos modifique alguna configuración de php que tenga como resultado una función de hash diferente utilizada por crypt? Como dijo por @Gareth pasando la contraseña completa de la base de datos puede resolver este problema. – krtek

+0

Empiezo a pensar en las líneas que sugiere Krtek: cuando el sistema se ha vuelto inestable, si genero una nueva cripta() (es decir, un ejemplo muy simple en el que establezco una variable en una cadena, la encripto y luego la comparo con la cripta) - Todo funciona bien. Cuando reinicio el servidor, de nuevo todo vuelve a funcionar. Así que definitivamente me estoy inclinando hacia algo que está cambiando el algoritmo utilizado para calcular el resultado de la cripta() ... ¿alguna reflexión sobre qué podría causar que esto suceda? Imprimí los valores de CRYPT_STD_DES, etc. y no cambian entre reinicios. –

Respuesta

1

Podría ser el parche de seguridad Suhosin PHP que afecta a su función crypt(). Altera muchos de los métodos de cifrado/aleatorio y puede ser la causa de su problema.

Compruebe un phpinfo() y vea si 'suhosin' está en algún lugar de la página. Si está allí, busca inhabilitar algunas de sus funciones en la configuración de php.

+0

Gracias por sus comentarios, he comprobado el phpinfo() y no tiene ningún trozo suhosin mencionado en él, así que supongo que esto no se aplica. –

2

¿Por qué estás leyendo la sal? ¿Y cómo estás obteniendo la sal? Diferentes algoritmos usan diferentes métodos para incluir la sal en la salida.

sólo tiene que utilizar toda la salida de la función cripta como segundo argumento:

$crypted='Og12345678'; 
    if (crypt($_POST['password'], $crypted)==$crypted) { 
     .... 

Y pase DES simple? De Verdad?

La última vez que miré, la implementación de la cripta PHP llamaría a la función crypt() proporcionada por el sistema, por lo que si tiene broekn es más probable que sea su sistema operativo que PHP, pero no dijo cuál es su sistema operativo es.

+0

El sistema operativo es Windows Server 2008 SP2. Gracias por tus comentarios. –

+0

Solo dejándome agregar comentarios de una sola línea :) - He ajustado el código para usar la contraseña completa en el comando crypt() y esto no ayudó cuando el sistema salió mal nuevamente hace un momento. –

+0

Sí, Single Pass DES, el sistema fue escrito hace mucho tiempo y para ser honesto, no protege nada ni remotamente seguro, simplemente permite que las personas descarguen archivos del sitio. Todo el sitio está listo para volver a desarrollar una nueva tecnología en algún momento. Pero sí, punto tomado :) –

0

Me enfrenté al mismo problema. Desde que moví mi instalación de vTigerCRM a la máquina local, el inicio de sesión del usuario con las contraseñas previamente almacenadas comenzó a fallar. Parece que crypt() está regresando diferentes hashes en diferentes ambientes con los mismos argumentos:

El entorno local:

SYSTEM: Windows NT 6.1 build 7601 (Business Edition Service Pack 1) i586 
PHP: 5.3.5 

crypt('hello world','$1$ad0000000'): 

    $1$ad00000008tTFeywywdEQrAl9QzV.M1 

El entorno de producción:

SYSTEM: Linux 2.6.18-338.9.1.el5.lve0.8.32 #1 x86_64 
PHP: 5.3.5 

crypt('hello world','$1$ad0000000'): 

    $1$ad000000$8tTFeywywdEQrAl9QzV.M1 
+0

Apuesto a que no es un problema de crypt(), es jut de Windows: P ¿Qué ocurre si usa los mismos parámetros en otros sistemas operativos que no son Windows, como RedHat, Solaris, Debian? – Juan

1

tuve el mismo problema con crypt ... Tuve ese login-check trabajando en 2 servidores, pero cuando lo transfiero al más nuevo, finalmente deja de funcionar. Doy una vuelta con cifrado MD5 de la siguiente manera: En register.php

$encrypted = md5($_POST["pass"]); 
... 

Y luego, en login.php

$password = md5($_POST["password"]); 
if ($password == $row["hash"]) 
     { 
      // remember that user's now logged in by storing user's details in session 
      $_SESSION["id"] = $row["id"]; 
      $_SESSION['username'] = $_POST['username']; 
      $_SESSION['logged'] = 'Yes'; 
      // redirect to homepage 
      redirect("index.php"); 
     } 

Espero que ayude :)

Cuestiones relacionadas