25 septiembre 2013

Consejos prácticos a la hora de integrar criptografía

Me encuentro a diario con personas (principalmente gente que desarrolla o administradores de sistemas) que se encuentran en el proceso de mejorar la seguridad de sus productos / sistemas implementando criptografía como aliada.

Muchas veces se da el caso que existe más buena FE que conocimiento a la hora de abordar esa tarea, y se cometen errores muy inocentes que tiran por tierra el esfuerzo de adoptar una solución por haberla adoptado incorrectamente.

En este post me gustaría compartir 'tips' sobre cómo abordar estos procesos para que deriven en un mejor resultado.

Almacenamiento de contraseñas

Este es el punto en el que más fallos se cometen, en muchos casos debido a que existe mucha información 'legacy' muy bien posicionada en Google a la que llega la gente y la usa como referencia.

Veamos consejos a la hora de realizar esta tarea:
  • Olvida y entierra la tentación de cifrar la base de datos con una única contraseña y almacenar dentro las contraseñas en claro. No, ese esquema no es seguro, delegas toda la seguridad en una única contraseña que resulta fácil de obtener (por ejemplo revisando el código del programa que cargue esa base de datos). Nunca utilices criptografía reversible para guardar contraseñas
  • Fundamental: OBVIA EL ALGORITMO MD5, sí, es seguro que vas a ver muchos ejemplos en Google que hablan de MD5, de hecho se sigue usando en otras tareas, pero nunca es aconsejable su uso para esta tarea. En su lugar usa SHA-512, penaliza el rendimiento con respecto a MD5, pero es algo imperceptible
  • Emplea técnicas de 'salting' a la hora de almacenar el hash de la contraseña. Usar salt significa que, si la contraseña es 123456, en vez de guardar la representación de 123456 en su forma 'hasheada' lo que haces es introducir otro elemento que impida a un atacante usar un listado de hashes de contraseñas ya precompilado. Es decir, lo que guardas es salt+123456 que obviamente genera un hash diferente a 123456 (y que un atacante podría tener ya hasheado con lo que se ahorra el proceso criptográfico). En un típico esquema de usuario / contraseña para una aplicación web, es ideal usar el correo electrónico como salt ya que es un dato conocido y accesible (normalmente se envían correos de confirmación de altas) de forma que, en el ejemplo antes descrito, al final el hash se haría contra fulano@mengano.com+123456
  • De nota: Usa PBKDF2 sobre los hashes que guardes. PBKDF2 es un estándar RSA para derivación de claves. Sin entrar en las profundidades matemáticas, lo que hace PBKDF2 es hacer más costoso el tiempo de computación de un hash. Los algoritmos de la rama SHA son algoritmos que han sido diseñados para ser rápidos, es decir, para que el costo computacional no sea elevado, eso, visto desde nuestra perspectiva, significa que los hashes que vamos a almacenar si usamos únicamente SHA se pueden atacar por fuerza bruta a un costo muy pequeño. Si usamos PBKDF2 lo que vamos a hacer es que, generar el hash, 'cueste' bastante más. Como decía al principio esto es de nota y SÍ va a tener un impacto notable a la hora de procesar peticiones de login en tu aplicación. Para una aplicación pequeña y que requiera máxima seguridad, ideal. Para un Facebook, probablemente no. Existen implementaciones de PBKDF2 en todos los lenguajes típicos
Cifrar datos

Vamos a abordar el tema de cifrar datos, una práctica muy deseable a la hora de trabajar con documentos o con datos.
  • Evita el uso de los algoritmos DES y RC4. En el caso de DES principalmente porque hay alternativas mucho mejores en cuanto a algoritmos de cifrado 'de bloque', el tiempo que inviertas en implementar uno mejor, va a ser idéntico a usar el desfasado DES. En el caso de RC4 la cosa cambia, es un algoritmo 'simpático', muy fácil de implementar al ser 'de flujo'. No requiere complicarse y por tanto resulta tentador usarlo (honestamente, para un desarrollo cuyo nivel de seguridad sea bajo puede ser una opción)
  • Cuando uses un algoritmo 'de bloque', como AES, GOST o Blowfish, siempre usa el modo 'CBC' que impide que un mismo dato tenga el mismo aspecto en diferentes puntos de los datos cifrados. Si usas, por ejemplo, el modo ECB, significa que la representación cifrada de 'securitybydefault' siempre tendrá el mismo aspecto una vez cifrado, lo que puede facilitar el criptoanálisis. 
Desplegar SSL

Vamos con la forma más optima de desplegar un servicio bajo SSL
  • Usa certificados de 2048 bits. Ahora es lo mínimo exigible, de hecho, muchas CAs no admiten peticiones por debajo de esa longitud.
  • Mejor certificados EV que certificados convencionales. Eso sí, son más costosos en tiempo y dinero. Siempre puedes empezar con uno tradicional e ir preparando los requerimientos de un certificado EV.
  • Deshabilita SSL v2. Hoy día no existen razones reales de compatibilidad que hagan necesario el uso de esa versión del protocolo
  • Obvia algoritmos de baja calidad, en concreto RC4, aunque lo deseable es configurar tu servidor para que solo use algoritmos de alta seguridad
  • Habilita en tu servidor el uso de 'HTTP Strict Transport Security' esto instruye al navegador para que, una vez visitado un sitio bajo SSL, se niegue a hacerlo bajo HTTP lo que protege a tus usuarios de ataques 'sslstrip'

7 comments :

SiD dijo...

Siempre aprendo cosas nuevas contigo.


Muchas gracias.

Alberto dijo...

Estupendo artículo! Que piensas de servicios tipo Lastpass (passwords y credenciales almacenadas en servidores externos) y de 1password (almacenamiento en local)? Recomiendas este tipo de servicios? alguna otra alternativa? Saludos y gracias. Alberto

María García dijo...

¿Y qué extensiones se recomiendan para que funcione lo de HSTS, por ejemplo, en Chrome y en FireFox? Yo tenía algunas (que, por cierto, me han desaparecido, no sé por qué, con la última actualización) para forzar los del https siempre que sea posible. Pero creo que no es exactamente lo mismo; ya que si no puede ir por https, va por http; lo que, imagino lo haría susceptible de un ataque SSLStrip. ¿O para el navegador es automático y basta con que el servidor lo implemente?

Por favor, no me mandéis a Google, que ya lo he buscado, no lo encuentro, no tengo mucho tiempo y os hago mucho la pelota en Twitter. ;-) Si alguien lo sabe, que lo diga.

Por cierto, (aunque seguramente por aquí todo el mundo ya lo sabe) www.ssllabs.com sirve para ver si un servidor implementa HSTS

María García dijo...

Me respondo yo a mí misma:

https://addons.mozilla.org/en-US/firefox/addon/force-tls/?src=collection&collection_id=26aa4d81-029d-8a7f-56d9-8b85087d4e18

Ruben D dijo...

Hola, entiendo que el 'hashing' con salt la mejor forma de proteger las claves de usuarios, pero cuando es necesario visualizar esas claves no queda otra que utilizar cifrado reversible.

En mi trabajo necesito almacenar una gran cantidad de claves de acceso a servidores y servicios que no son controladas por mi, por lo que utilizo una aplicacion que he desarrollado para este fin. La aplicación está escrita en php y utiliza AES en modo CBC y la clave no es almacenada en el codigo, sino que es encriptada con el hash de la clave del usuario, asi cuando un usuario accede se le pide la clave maestra (la primera vez o cuando cambia), y se guarda en la bd de la forma indicada, para que cada vez que acceda pueda desencriptarla y utilizarla en la sesión.

Le he dado muchas vueltas a este asunto, pero no encuentro otra manera de utilizar el cifrado de una manera no muy intrusiva. Te parece correcto?

Excelente articulo que ayuda a difundir de una manera sencilla la correcta aplicación de la criptografía

Un saludo

Angel dijo...

Excelente CLASE MAGISTRAL con mayúsculas, como siempre Yago!!! Un abrazo a todos por SbD XD

alberto dijo...

Yo uso rijndael, la clave es el hash del password en sha384, donde los 256bits primeros son la clave y los 128bits restantes son el vector de inicializacion...my pregunta es, es suficiente? No soy experto ni nada, solo un programador k esta aciendo una mini aplicacion para mi mismo donde almacenar mis contraseñas.