2010-06-03 15 views
9

Estoy desarrollando una pequeña aplicación web que autentica internamente a los usuarios. Una vez que el usuario se autentica, mi aplicación web pasa cierta información, como el ID de usuario y el nombre de la persona, a una aplicación web de un tercero. El desarrollador externo está sugiriendo que hagamos hash y sal de los valores.Hashing and Salaring values ​​

Perdona mi ignorancia, pero ¿qué significa exactamente eso?

Estoy escribiendo la aplicación en Java. Entonces, lo que planeo hacer es mezclar el ID de usuario, el nombre de la persona y algún valor Math.random() como sal con Apache Commons Digest Utils SHA512 y pasar esa cadena hash junto con el ID de usuario y el nombre de la persona.

¿Es esa la práctica estándar? Debería pasar al tercero la sal y corregir?

+0

Me entretiene que tantas respuestas a esta pregunta saltaron sobre el título y respondieron a la pregunta no relacionada "¿qué significa salaring una contraseña?". – dimo414

Respuesta

14

Una sal se usa normalmente para almacenar contraseñas de contraseñas de forma segura. Hashing una contraseña para almacenamiento o comunicación (para que no pueda ser leído por otros) es vulnerable a la descodificación usando rainbow tables. Ahora, cuando agrega una cadena aleatoria a la contraseña, pero almacena la cadena con el hash, esto se vuelve mucho más difícil. El cálculo de esta nueva almohadilla se ve así:

hash(password + salt) 

o incluso

hash(hash(password) + salt) 

Para conectarse de forma segura en un sitio web de terceros, puede enviar el ID de usuario, el hash con sal (desde arriba) y la sal que utilizó (si no está dado). Dependiendo de cómo ese sitio web almacenó sus contraseñas, puede generar la sal para usted o puede pedir una sal.

Una opción es enviar primero el ID de usuario al sitio web, luego dejar que responda con la sal, y luego enviar el hash(password+salt)) al sitio web.

+0

AFAIK haciendo dos hash (como su segundo ejemplo) será más débil, criptográficamente. Creo que la razón es que cualquier £ $%^& caracteres en la contraseña se cambiará a letras/números, por lo que se necesitan menos valores en la tabla del arco iris. –

+0

¿Tenía la impresión de que un sitio web de un tercero no podría acceder a mi objeto de sesión incluso con la identificación de sesión correcta? quizás estoy equivocado? – Avanst

+0

Ah, lo siento, he entendido mal su pregunta. Voy a editar mi anwer. – Marc

1

Una vez que el usuario se autentica mi aplicación web pasa entonces algunos datos tales como el nombre ID de usuario y de la persona a una tercera aplicación web partido. El desarrollador externo está sugiriendo que hagamos hash y sal de los valores.

Eso no suena bien. Los hash son operaciones de una sola dirección. No se puede tomar el resultado de un hash y adivinar el texto plano de ella

Lo que estoy planeando hacer hash se el ID de usuario, nombre de persona, y algún valor Math.random() como la sal

Para cualquier texto llano dado, debe usar la misma sal o el hash resultante será diferente. Por lo tanto, si va a utilizar una sal aleatoria o generada, debe almacenarla junto con el hash de la contraseña.

usando SHA-256 o SHA-512 está muy bien y es lo NIST recommends

+2

¿qué quiere decir que para cualquier texto llano dado necesita usar la misma sal? El objetivo de una sal es que un mismo texto puede tener billones de diferentes resultados * hash (texto sin formato + sal) *, lo que imposibilita los ataques de "tablas del arco iris". Por ejemplo, en los sistemas Un * x, puede tener dos usuarios que eligen la misma contraseña, pero esa contraseña tendrá dos valores hash diferentes, porque se usa una sal diferente (guardada junto con la contraseña hash). – NoozNooz42

+1

Creo que está malinterpretando lo que dice: si la sal es diferente, el hash resultante será diferente incluso con el mismo texto sin formato. – dimo414

8

En Java se puede hacer algo como:

import org.apache.commons.codec.digest.DigestUtils; 
import org.apache.commons.lang.RandomStringUtils; 

/** 
* SHA1-hash the password with the user's salt. 
* 
* @param password 
*/ 
public void setPassword(String password) 
{ 
    if (password.equals(this.password)) 
    { 
     return; 
    } 

    if (passwordSalt == null || passwordSalt.equals("")) 
    { 
     passwordSalt = RandomStringUtils.randomAscii(20); 
    } 

    this.password = DigestUtils.shaHex(password + passwordSalt); 
} 

/** 
* Check if a given password is correct. 
* 
* @param givenPassword 
* @return True is correct, else false. 
*/ 
public boolean checkPassword(String givenPassword) 
{ 
    return (password.equals(DigestUtils.shaHex(givenPassword + passwordSalt))); 
} 

A continuación, la contraseña no es legible, incluso si un hacker roba su DB.

+0

Debe devolver la contraseña, también, quizás con un getter. –

+0

+1 para usar ** apache commons codec lib **! Descárguelo de apache.org aquí: [commons-codec-1.9.jar] (http://commons.apache.org/proper/commons-codec/) –

0

El punto entero de una sal es hacer ataques usando lo que se denomina "tablas de arco iris" inviable (desde un punto de vista probabilístico: si se toma una parte suficientemente grande de hash, entonces se vuelve prácticamente imposible calcular previamente el arco iris mesas).

http://en.wikipedia.org/wiki/Rainbow_table

en vez de hacer un hash (un) y almacenar el hash:

:460526e74fd6a25b525e642db2f756a4: 

haces de hash (a + sal) y se almacena el hash y la sal (la sal se puede seleccionar al azar):

:cdd5bc3f05f6a76f6c82af728b2c555c:346884e6e35be: 
3

Sólo un aviso, hay hay alguna desinformación sobre qué hacer con la sal. Está bien y es normal guardar la sal. Cada contraseña debe tener su propia sal que se almacena en texto sin formato junto con ella. Está destinado a hacer que sea mucho más difícil para alguien que ya ha robado su base de datos de contraseñas hash descifrarlo utilizando una tabla hash calculada previamente.

Por lo que si usted debe enviar a un tercero la sal, tendré que tener un poco más de información. Quien esté tomando la contraseña suministrada por el cliente durante la autenticación, la mezcla y la compara con la versión previamente hash, necesita la sal para que la contraseña que el cliente proporciona para la autenticación se pueda convertir exactamente igual que antes.

1

Me gustaría ver si no puede encontrar más información o algunos ejemplos de esta aplicación de terceros con la que está trabajando. Lo que describes no parece una práctica común, y honestamente ni siquiera tiene mucho sentido en base a lo que has dicho.

Usted autentica al usuario en su programa (varias respuestas parecen estar abordando este problema, y ​​sí, debe almacenar las contraseñas de los usuarios como hashes salados, pero eso es todo un problema y luego, al autenticarlas, están pasando cierta información a esta aplicación de terceros. Ahora, depende de lo que se supone que esta aplicación debe hacer/saber exactamente. Si necesita conocer el ID de usuario, por ejemplo, entonces no puede hash/salt antes de enviarlo, porque la aplicación nunca podrá recuperar el ID de usuario original. Por otro lado, si la aplicación simplemente necesita algún tipo de identificador para reconocer solicitudes, y hash userID + userName es simplemente una sugerencia , entonces esto tiene sentido, básicamente estás generando una cadena única pero no decodificable por el usuario para que lo use la aplicación de terceros, básicamente como una clave de sesión.

Si ese segundo camino es lo que están tratando de tener que hacer, es una forma un tanto extraña (y no muy seguro) de tratamiento de las solicitudes, pero parece bien para mí.

Así que como he dicho, a ver si se pueden encontrar algunos ejemplos, o incluso si desea publicar más información sobre la aplicación en cuestión aquí, y podemos tomar un vistazo a nosotros mismos.