PHP - Encriptación de contraseñas

SeiYa

Buenas ... esto es un tema un poco peliagudo, he puesto php en la cabecera pero en general puede aplicarse a cualquier lenguaje ...

El tema es ... ¿Qué método de cifrado utilizáis para almacenar las contraseñas?

Yo ahora uso MD5 que viene integrado en PHP pero he estado navegando un poco y es bastante fácil con las rainbow tables sacar a partir de un hash su texto plano correspondiente.

Entonces ... ¿como mejorar en ese aspecto la seguridad?

¿Es posible aplicar a un hash MD5 una encriptación MD5 para obtener un hash de un hash? de ser así se obtendría una seguridad mayor, ya que las tablas arcoiris estas no creo que contemplen hashes de hashes ...

De todos modos ... ¿qué sistemas utilizáis y por qué?

Un saludo.

EDIT:

1: pass = 123456
hash1 = e10adc3949ba59abbe56e057f20f883e
hash2 = 14e1b600b1fd579f47433b88e8d85291
hash3 = c56d0e9a7ccec67b4ea131655038d604

He hecho una prueba, una pass típica, 123456.

El Hash1 es su primera codificación, el 2 es la codificación del hash1 y el 3 es la codificación del hash2.

En lugar de aplicar una codificación aplicar 3 veces la misma.

El primer hash si le pones en google ya tienes resultados y lo mismo si le pones en cualquier descifrador de md5 de esos online que hay, sin embargo, el segundo, a pesar de salir en google, no conseguirás sacarle con las rainbow tables por que sino me equivoco no tienen una rainbo table para contraseñas tan largas.

Si aún así aplicamos una tercera codificación se puede conseguir un cifrado de contraseña bastante sólido ...

IS4kO

Sin duda md5 es uno de los algoritmos mas utilizados, pero como has comprobado, es bastante vulnerable...

Pero antes que preguntar que tipo de algoritmo es más adecuado, habría que decidirse por el tipo de encriptación a realizar, esta puede ser simétrica o asimétrica

Simétrica:

Se basa en que utiliza la misma clave para cifrar y descifrar mensajes por lo que las dos partes que se comunican han de ponerse de acuerdo de antemano sobre la clave a usar. Es decir, que si no tienes esa clave, es imposible, descifrar el codigo encriptado.... Imposible entre comillas claro, y es que tenemos que darnos cuenta de que cualquier estructura que siga un patrón antes o despues puede ser descifrada, pero justo en este punto es donde entran los Algoritmos como MD5, que intentan que dichos patrones sean lo más abstractos y cambiantes posibles

Asimétrica:Este método consiste en generar una pareja de llaves, una publica y una privada. Es decir, el emisor tiene una clave de encriptación, publica que puede o no ser descifrada (cosa que no compromete la seguridad), a partir de la cual cifra un mensaje. Una vez cifrado se lanza hacia el receptor, el cual tiene una clave privada, que solo sabe el, a través de la cual descifra el mensaje. El algoritmo más extendido sobre este tipo de encriptacion es el RSA,
(+ Info: http://www.pajhome.org.uk/crypt/rsa/index.html )

Tras leer esta explicación, muchos elegirían una encriptación de tipo asimétrica, ya que es mucho mas robusta y completa, pero esto no siempre es la mejor elección, ya que este tipo de encriptación requiere tal suma de recursos que en ocasiones no merece la pena el esfuerzo....

Bueeeno pues dicho esto centremonos en la criptografiía simétrica, que es la más común y la que todos acabamos usando. Y entre los algoritmos mas usados tenemos

DES: Que toma un texto claro de una longitud fija de bits y lo transforma mediante una serie de complicadas operaciones en otro texto cifrado de la misma longitud.

La clave de cifrazo mide 64 bits, aunque en realidad, sólo 56 de ellos son empleados por el algoritmo. Los ocho bits restantes se utilizan únicamente para comprobar la paridad, y después son descartados.

(+ Info: http://en.wikipedia.org/wiki/Data_Encryption_Standard)

Triple DES Que consiste en aplicar tres veces el algoritmo DES sobre la misma clave, de tal forma que la clave final de encriptación tendrá una longitud de 168 bits

(+ Info: http://csrc.nist.gov/publications/nistpubs/800-67/SP800-67.pdf )

AES: También conocido como Rijndael, aunque estrictamente hablando AES no es precisamente Rijndael (aunque en la práctica se los llame igual) ya que Rijndael permite un mayor rango de tamaño de bloque y clave; AES tiene un tamaño de bloque fijo de 128 bits y tamaños de llave de 128, 192 ó 256 bits, mientras que Rijndael puede ser especificado por una clave que sea múltiplo de 32 bits, con un mínimo de 128 bits y un máximo de 256 bits.

(+ info: http://www.quadibloc.com/crypto/co040401.htm)

RESUMIENDO:

Lo mas importante a la hora de elejir como encriptar un mensaje (digamos que de forma profesional, con algoritmos contrastados, etc..), es elegir un método atendiendo a las necesidades y a la aplicación que va a tener el cifrado.

Para trabajos de intercambio de grandes cantidades de información, la encriptación asimétrica no es recomendable, a no ser que sea realmente necesario un nivel de seguridad muy alto, y tengamos la posibilidad de poseer unos mega servidores

Pero tb hay casos en los que aunque la cantidad de información, sea escasa, como por ejemplo encriptación de contraseñas, no sea optimo, o si... si necesitamos una autenticacion web que requiera usar este algoritmo, para conexiones multiples concurrentes... bien, podemos tumbar un servidor como haya 5 o 6 usuarios intentandose autenticar a la vez... (aunque luego tengamos procedimientos de hilos y demas para intentar optimizar)

Así que mi opinión personal, y despues de todo lo explicado, y por experiencia, yo siempre he elegido, encriptación simétrica y AES (Rijndael)

LOc0

Cuando tenía mi web usaba MD5 con un salt aleatorio de 5 caracteres. El hash final era md5(md5($pass).md5($salt)) En la cookie guardaba el hash de la combinación.

Ejemplo:

Pass: "elpollopepeyeeslapolla" -> 3cc68cd9a62b19eac2c339a6c7245340

Salt aleatorio (se genera por primera vez al registrarse en la web): "g6!lJ" -> c0ed979630ce4f0d1f9ef774edbd6fe2

HASH final -> bf3c7020cbc75aefca7cead2ec7cdad1

En la BD guardaba el hash final, que tb guardaba en la cookie.

Hay 2128 posibles hash MD5 distintos. Para meterlas todas harían falta unas tablas enormes y muuucho tiempo de cálculo. ¿Posibles colisiones? Claro, ya que hay infinitas cadenas posibles frente a 2128 hashes. De todas formas yo veo chungo que de la casualidad de que por ejemplo, una cadena tipo "12345" tenga el mismo hash que "jhdjasdhasdasjdhakshdahsjdhjasd73127379123hj"...

Aún así, como ya es sabido, ni MD5, ni SHA, etc... son métodos de cifrado y no deben usarse como tal. Si quieres seguridad, yo me iría a AES en simétrica y RSA en asimétrica.

Salu2 ;)

kas

Como dijo un profe:

Encriptar es meter en cripta. Nosotros queremos cifrar.

A

Yo te diría que usases Blowfish, Twofish, 3DES o Tea. De los que hay son de lo mejor y están bastante probados.

BlisZ

yo lo que hago es eso, md5(md5(md5($pass))) y listo

elkaoD

#4, como dijo cualquier persona :

Las metáforas existen. Los purismos lingüísticos a la mierda, aunque a la mayoría de la gente de ciencias no le entre en la puta cabeza.

GATE_Anthrax

Si quereis mejorar vuestra seguridad de MD5 al enviarlas, por miedo a que alguien la snife, podeis hacer varias cosas.

Hacer salt, encriptarla varias veces, o la que creo que es mejor, encriptarla en la maquina del cliente antes de enviarla, con Javascript. Aqui teneis el codigo necesario:
http://pajhome.org.uk/crypt/md5/md5src.html

Va de lujo. Y si además quereis encriptarla varias veces en md5 o salarla, podeis.

Usuarios habituales

  • GATE_Anthrax
  • elkaoD
  • Archville
  • kas
  • LOc0
  • IS4kO
  • SeiYa