tipos source softwares software proyecto open libres libre historia ejemplos codigo abierto security open-source encryption salt rainbowtable

security - source - Salt Generation y software de código abierto



softwares libres (6)

Según tengo entendido, la mejor práctica para generar sales es usar alguna fórmula críptica (o incluso constante mágica) almacenada en tu código fuente.

Estoy trabajando en un proyecto que planeamos publicar como código abierto, pero el problema es que con la fuente viene la fórmula secreta para generar sales y, por lo tanto, la capacidad de ejecutar ataques de tabla de arco iris en nuestro sitio.

Me imagino que mucha gente ha contemplado este problema antes que yo, y me pregunto cuál es la mejor práctica. Me parece que no tiene sentido tener una sal en absoluto si el código es de código abierto, porque las sales pueden modificarse fácilmente mediante ingeniería inversa.

¿Pensamientos?


Desde que Unix se hizo popular, la forma correcta de almacenar una contraseña ha sido agregar un valor aleatorio (el salt) y hash it. Guarda la sal donde puedas llegar más tarde, pero donde esperas que los malos no la tengan.

Esto tiene algunos buenos efectos. En primer lugar, los tipos malos no pueden hacer una lista de las contraseñas esperadas como "Contraseña1", ponerlas en una tabla de arcoíris y revisar el archivo de contraseñas buscando coincidencias. Si tienes una buena sal de dos bytes, tienen que generar 65,536 valores para cada contraseña esperada, y eso hace que la tabla rainbow sea mucho menos práctica. En segundo lugar, si puede mantener la sal de los tipos malos que están buscando su archivo de contraseñas, ha hecho que sea mucho más difícil calcular los valores posibles. En tercer lugar, ha hecho que sea imposible para los malos determinar si una persona determinada usa la misma contraseña en diferentes sitios.

Para hacer esto, generas una sal aleatoria. Esto debería generar cada número en el rango deseado con probabilidad uniforme. Esto no es difícil; un simple generador de números aleatorios congruenciales lineales funcionará muy bien.

Si tienes cálculos complicados para hacer la sal, lo estás haciendo mal. Si lo calcula en función de la contraseña, lo hará de forma incorrecta. En ese caso, todo lo que está haciendo es complicar el hash y no agregar sal funcionalmente.

Nadie bueno en seguridad se basaría en ocultar un algoritmo. La criptografía moderna se basa en algoritmos que han sido ampliamente probados, y para ser ampliamente probados deben ser bien conocidos. En general, se ha encontrado que es más seguro usar algoritmos estándar en lugar de rodar uno propio y esperar que sea bueno. No importa si el código es de código abierto o no, todavía es posible que los malos analicen lo que hace un programa.


En el caso de una aplicación de escritorio que encripta datos y los envía a un servidor remoto, ¿cómo considera usar una sal diferente cada vez?

Usando PKCS # 5 con la contraseña del usuario, necesita una sal para generar una clave de cifrado, para encriptar los datos. Sé que mantener la sal codificada (ofuscada) en la aplicación de escritorio no es una buena idea.

Si el servidor remoto NUNCA debe conocer la contraseña del usuario, ¿es posible utilizar sal diferente cada vez? Si el usuario usa la aplicación de escritorio en otra computadora, ¿cómo podrá descifrar los datos en el servidor remoto si no tiene la clave (no está codificada en el software)?


Realmente las sales solo necesitan ser únicas para cada entrada. Incluso si el atacante puede calcular qué es la sal, hace que la tabla del arcoíris sea extremadamente difícil de crear. Esto se debe a que la sal se agrega a la contraseña antes de que sea hash, por lo que se agrega efectivamente al número total de entradas que la tabla rainbow debe contener para tener una lista de todos los valores posibles para un campo de contraseña.


Use un generador de funciones aleatorias para generar la sal, y guárdela en la base de datos, haga sal una por fila y guárdela en la base de datos.

Me gusta cómo se genera sal en django-registration. Referencia: http://bitbucket.org/ubernostrum/django-registration/src/tip/registration/models.py#cl-85

salt = sha_constructor(str(random.random())).hexdigest()[:5] activation_key = sha_constructor(salt+user.username).hexdigest() return self.create(user=user, activation_key=activation_key)

Utiliza una combinación de sha generado por un número aleatorio y el nombre de usuario para generar un hash.

Sha sí es conocido por ser fuerte e irrompible. Agregue múltiples dimensiones para generar la sal en sí, con número aleatorio, sha y el componente específico del usuario, ¡tiene una seguridad irrompible!


Dado que las preguntas sobre los hashes de sal se producen de manera bastante regular y parece que hay bastante confusión sobre el tema, amplié esta respuesta.


¿Qué es una sal?

Una sal es un conjunto aleatorio de bytes de una longitud fija que se agrega a la entrada de un algoritmo hash.


¿Por qué es útil salar (o siembra) un hash?

Agregar una sal aleatoria a un hash garantiza que la misma contraseña produzca muchos hashes diferentes. La sal generalmente se almacena en la base de datos, junto con el resultado de la función hash. Salar un hash es bueno por una serie de razones:

  1. La salazón aumenta en gran medida la dificultad / costo de los ataques precomputados (incluidas las tablas de arcoíris )
  2. Salting se asegura de que la misma contraseña no dé como resultado el mismo hash. Esto asegura que no puede determinar si dos usuarios tienen la misma contraseña. Y, lo que es más importante , no puede determinar si la misma persona usa la misma contraseña en diferentes sistemas.
  3. La salazón aumenta la complejidad de las contraseñas, lo que disminuye en gran medida la efectividad de los ataques de Dictionary- y de cumpleaños . (Esto solo es cierto si la sal se almacena separada del hash).
  4. La salazón adecuada aumenta en gran medida la necesidad de almacenamiento de ataques de precomputación, hasta el punto en que ya no son prácticos. (Las contraseñas alfanuméricas sensibles a las mayúsculas y minúsculas de 8 caracteres con sal de 16 bits, con hashes a un valor de 128 bits, ocuparían poco menos de 200 exabytes sin reducción del arco iris).


No hay necesidad de que la sal sea secreta.

Una sal no es una clave secreta, en cambio una sal ''funciona'' al hacer que la función hash sea específica para cada instancia. Con hash salado, no hay una función de hash, sino una para cada valor de sal posible. Esto evita que el atacante ataque contraseñas N hashed por menos de N veces el costo de atacar una contraseña. Este es el punto de la sal.
Una "sal secreta" no es una sal, se llama "clave", y significa que ya no está computando un hash, sino un Código de Autenticación de Mensaje (MAC). La computación MAC es un asunto complicado (mucho más complicado que simplemente juntar una clave y un valor en una función hash) y es un tema muy diferente.

La sal debe ser aleatoria para cada instancia en que se use. Esto asegura que un atacante tiene que atacar cada hash salado por separado.
Si confías en que tu sal (o algoritmo de salazón) es secreta, ingresas a los dominios de Seguridad a través de la oscuridad (no funcionará). Lo más probable es que no obtenga seguridad adicional del secreto salino; solo tienes la cálida sensación confusa de seguridad. Entonces, en lugar de hacer tu sistema más seguro, simplemente te distrae de la realidad.


Entonces, ¿por qué la sal tiene que ser aleatoria?

Técnicamente, la sal debe ser única . El punto de la sal es ser distinto para cada contraseña hash. Esto se entiende en todo el mundo . Como no existe una organización central que distribuya sales exclusivas bajo demanda, debemos confiar en la siguiente mejor opción, que es la selección aleatoria con un generador aleatorio impredecible, preferiblemente dentro de un espacio saliente lo suficientemente grande como para hacer que las colisiones sean improbables (dos instancias usando el mismo valor de sal).

Es tentador tratar de derivar una sal de algunos datos que es "presumiblemente único", como la identificación del usuario, pero tales esquemas a menudo fallan debido a algunos detalles desagradables:

  1. Si utiliza, por ejemplo, la identificación de usuario , algunos tipos malos que atacan a distintos sistemas pueden agrupar sus recursos y crear tablas precalculadas para las ID de usuario de 1 a 50. Una identificación de usuario es única en todo el sistema, pero no en todo el mundo .

  2. Lo mismo se aplica al nombre de usuario : hay una "raíz" por sistema Unix, pero hay muchas raíces en el mundo. Una mesa de arcoiris para "raíz" valdría la pena, ya que podría aplicarse a millones de sistemas. Peor aún, también hay muchos "bob", y muchos no tienen la capacitación de administrador del sistema: sus contraseñas podrían ser bastante débiles.

  3. La unicidad es también temporal. A veces, los usuarios cambian su contraseña. Para cada nueva contraseña , se debe seleccionar una nueva sal . De lo contrario, un atacante obtuvo el hash de la contraseña anterior y el hash de la nueva podría intentar atacar a ambos simultáneamente.

Usar una sal aleatoria obtenida de un PRNG criptográficamente seguro e impredecible puede ser algún tipo de exageración, pero al menos puede protegerte contra todos esos peligros. No se trata de evitar que el atacante sepa qué es una sal individual , se trata de no darles el objetivo grande y gordo que se utilizará en un número considerable de objetivos potenciales. La selección aleatoria hace que los objetivos sean lo más delgados posible.


En conclusión:

Use una sal de alta entropía aleatoria, distribuida uniformemente. Use una sal nueva cada vez que cree una nueva contraseña o cambie una contraseña. Almacene la sal junto con la contraseña hash. Favor de grandes sales (al menos 10 bytes, preferiblemente 16 o más).

Una sal no convierte una contraseña incorrecta en una buena contraseña. Solo se asegura de que el atacante pague al menos el precio de ataque del diccionario por cada contraseña incorrecta que rompa.


Fuentes útiles:
.com: sal no aleatoria para hashes de contraseñas
Bruce Schneier: Criptografía práctica (libro)
Matasano Security: suficiente con las tablas Rainbow
usenix.org: la cripta de Unix usó sal desde 1976
owasp.org : ¿Por qué agregar sal?
openwall.com : Salts

Renuncia:
No soy un experto en seguridad. (Aunque esta respuesta fue revisada por Thomas Pornin )
Si alguno de los profesionales de seguridad encuentra algo incorrecto, por favor comente o edite esta respuesta wiki.


Puede generar una sal aleatoria para cada registro en tiempo de ejecución. Por ejemplo, supongamos que está almacenando contraseñas de usuario hash en una base de datos. Puede generar una cadena aleatoria de 8 caracteres alfanuméricos en mayúsculas y minúsculas en tiempo de ejecución, anteponerla a la contraseña, hash esa cadena y almacenarla en la base de datos. Dado que hay 62 8 sales posibles, la generación de tablas arcoiris (para cada sal posible) será prohibitivamente costosa; y dado que está utilizando una sal única para cada registro de contraseñas, incluso si un atacante ha generado un par de tablas de colores iguales, aún no podrá descifrar todas las contraseñas.

Puede cambiar los parámetros de su generación de sal en función de sus necesidades de seguridad; por ejemplo, podría usar una sal más larga, o podría generar una cadena aleatoria que también contenga signos de puntuación, para aumentar la cantidad de sales posibles.