Thread View: es.comp.lenguajes.java
12 messages
12 total messages
Started by Guevonaso
Fri, 16 Feb 2007 07:41
Almacenar contraseña
Author: Guevonaso
Date: Fri, 16 Feb 2007 07:41
Date: Fri, 16 Feb 2007 07:41
17 lines
1823 bytes
1823 bytes
Buenas. Tengo el siguiente dilema para una aplicación Swing que se conecta a un servidor, hasta ahora las contraseñas del usuario siempre las almacenaba encriptadas con MD5 o SHA y las enviaba encriptadas y era el servidor el encargado de verificar que podria ser válida o no. Asi no hay problema al guardar una contraseña en la "plano" en un fichero . El problema ahora es que tengo que enviar la contraseña original, y por lo tanto no puedo hacerlo así. ¿Que otra manera tengo de almacenar esta contraseña en un fichero .properties de una manera segura? No controlo mucho el tema de seguridad y encriptación ¿que puedo hacer? Un saludo.
Re: Almacenar contraseña
Author: Eduardo Yáñez Parareda
Date: Fri, 16 Feb 2007 08:23
Date: Fri, 16 Feb 2007 08:23
5 lines
1118 bytes
1118 bytes
> El problema ahora es que tengo que enviar la contrase�a original, y > por lo tanto no puedo hacerlo as�. �Que otra manera tengo de almacenar > esta contrase�a en un fichero .properties de una manera segura? Encripta el .properties
Re: Almacenar contraseña
Author: Ricardo Palomares Martinez
Date: Fri, 16 Feb 2007 21:00
Date: Fri, 16 Feb 2007 21:00
159 lines
7970 bytes
7970 bytes
Guevonaso escribió:
> Tengo el siguiente dilema para una aplicación Swing que se conecta a
> un servidor, hasta ahora las contraseñas del usuario siempre las
> almacenaba encriptadas
Seguro que no, salvo que las metieses en una sala cerrada,
posiblemente excavada en la tierra, que es la única acepción que
podría entenderse, por cercanía lexicográfica, en caso de existir el
verbo "encriptar" en castellano, que no es el caso.
A lo mejor quieres decir "cifradas", que es la traducción al español
del inglés "encrypted". :-)
> con MD5 o SHA y las enviaba encriptadas y era
> el servidor el encargado de verificar que podria ser válida o no. Asi
> no hay problema al guardar una contraseña en la "plano" en un
> fichero .
No entiendo esto de último de "...en la "plano" en un fichero".
¿Quieres decir que no guardabas las contraseñas sin cifrar?
Hay maneras alternativas a la que describes tú arriba. Más abajo
comento algunas ideas.
> El problema ahora es que tengo que enviar la contraseña original, y
> por lo tanto no puedo hacerlo así. ¿Que otra manera tengo de almacenar
> esta contraseña en un fichero .properties de una manera segura?
¿Por qué tienes que enviar la contraseña "original" (imagino que
quieres decir "sin cifrar")? ¿Tienes el servidor bajo tu control, y
con el servidor quiero decir no sólo la administración, sino la API de
servicios que ofrece?
Yo creo que tienes que dividir el problema en dos partes: una es el
almacenamiento de la contraseña de una manera segura, y otra es la
manera de asegurar que un par usuario-contraseña introducido en el
extremo del cliente puede validarse de alguna manera fiable teniendo
los datos en el lado del servidor.
El primer problema es obvio, cifrar lo que guardas. MD5 y SHA son
algunas opciones, pero he creído leer por ahí que MD5 no es muy
seguro, y no sé si SHA también puede romperse por fuerza bruta con las
máquinas actuales. Dependiendo de la criticidad de la aplicación, yo
que tú me informaría un poco sobre algoritmos (creo recordar que había
un sustituto de DES que era bastante seguro, pero no recuerdo el
nombre). Por definición, los algoritmos de cifrado seguros son
aquellos en los que la seguridad no la aporta la ocultación del
algoritmo, por lo que no deberías tener problemas para encontrar el
código fuente de la mayoría de ellos.
Otra cosa que se suele hacer es no cifrar o aplicar una función hash a
la contraseña sin más, sino a la concatenación de una contraseña y una
pizca de sal (http://www.nmrc.org/pub/faq/hackfaq/hackfaq-04.html#4.6).
La segunda parte es harina de otro costal. Lo primero que sería
deseable es que la contraseña nunca viaje por la red, ya sea cifrada o
sin cifrar (y esto no sólo al iniciar sesión, sino al cambiar la
contraseña; interesante, ¿verdad?). Si para hacer la validación tienes
una función en el servidor que te pide la contraseña y no puedes
cambiar esa función por otra (a esto me refería con lo de "control del
servidor"), mal comienzo.
Te cuento cómo lo resolvía Novell antiguamente en sus clientes IPX
(una descripción la tienes aquí:
http://www.nmrc.org/pub/faq/hackfaq/hackfaq-20.html#20.8, pero
obviamente se salta algunos pasos, como que el cliente tiene que pasar
al servidor el nombre del usuario en claro en algún momento). La
"conversación" que tenía lugar entre un cliente que quería iniciar
sesión en un servidor NetWare y éste venía a ser así:
01- El cliente envia un paquete "HELLO" al servidor para iniciar la
conversación de autenticación.
02- El servidor responde con un "HELLO" de cortesía, y en un par de
intercambios de mensajes más se ponen de acuerdo en las versiones
que tienen cada uno para encontrar el mejor algoritmo posible
(probablemente tú no necesites esto, pero que sepas que puede ser
un paso si vas a andar cambiando clientes y no todo el cambio se
hará a la vez).
03- Una vez puestos de acuerdo, el cliente le dice al servidor cómo se
llama el usuario (sin contraseña).
04- El servidor mira si el usuario existe y puede iniciar sesión
(limitaciones horarias, de dirección de red, cuenta bloqueada,
etc.). Si todo va bien, el servidor genera una semilla (un valor
aleatorio) y la pasa al cliente.
05- El cliente, que tiene la contraseña en claro introducida por el
usuario, usa un algoritmo hash (el mismo que en el servidor,
claro) con la concatenación del usuario y la contraseña, y al
resultado le vuelve a aplicar el algoritmo hash añadiendo la
semilla. Así obtiene un valor único para la sesión, y lo envía al
servidor.
06- El servidor hace lo mismo, y compara el resultado.
La contraseña no ha viajado en claro por la red, y no puede extraerse
de los paquetes que viajan fundamentalmente porque el algoritmo hash
es de un solo sentido (MD5 y SHA son algoritmos hash); si tienes el
nombre de usuario y el hash que has capturado por la red, no puedes
aplicar un algoritmo hash inverso para obtener la secuencia
usuario+contraseña. Además, la semilla es única por sesión.
Estadísticamente, para cuando consigas romper por fuerza bruta el
/cifrado/ con la semilla, la sesión habrá concluido.
A primera vista se me ocurre que quizá sería mejor usar una función de
cifrado reversible para la concatenación usuario+contraseña, pero no
sé ni de matemáticas ni de criptología lo suficiente para creer que
llevo razón. Una cosa que debes tener en cuenta es que el algoritmo
descrito en la URL que te paso tiene quince años; donde habla de 16 o
32 bytes puede que quieras doblar o cuadriplicar la longitud. En esa
época los ordenadores iban a 33 MHz, no a 3400. :-) Doblar la longitud
no supone doblar la dificultad, sino quizá multiplicarla por 2^128.
Por cierto, que en todo esto rollo verás que no he mencionado la
palabra "Java" ni una vez. Pero para que no quede tan "off-topic",
comentaré que durante finales de los 90, el CEO de Novell fue Eric
Schmidt, que lideró los inicios de Java. :-)
Hala, ya estamos on-topic. :-P
Windows NT usaba un esquema de desafío/respuesta, y creo recordar que
SSL también usa esto. Si buscas información sobre cómo funciona una
negociación de sesión de SSL, puedes obtener ideas básicas que
implementar.
Y ten presente que hay dos maneras de "robar" unas credenciales:
invirtiendo el cifrado de lo que viaja por la red, lo que no es
posible si se usan algoritmos hash, y probando combinaciones de
usuario y contraseña para iniciar sesión (ataque de fuerza bruta);
para esto último vienen bien las pizcas de sal y controles en el
servidor sobre intentos fallidos repetidos.
Saludos.
--
If it's true that we are here to help others,
then what exactly are the OTHERS here for?
Re: Almacenar contraseña
Author: Guevonaso
Date: Wed, 21 Feb 2007 12:37
Date: Wed, 21 Feb 2007 12:37
11 lines
1755 bytes
1755 bytes
Muchas gracias, sobre todo por las correcciones :) Efectivamente no tengo el servidor bajo mi control, la única manera que hemos encontrado de poder identificarnos con él es usando las contraseñas sin cifrar, de ahí que tenga que guardarlas en un fichero de texto .properties. La seguridad no es crítica, pues es una pequeña utilidad sin datos importantes, pero pretende ir creaciendo y no quisiera dejar esto así. Muchas gracias otra vez.
Re: Almacenar contraseña
Author: Guevonaso
Date: Wed, 21 Feb 2007 12:37
Date: Wed, 21 Feb 2007 12:37
6 lines
1484 bytes
1484 bytes
On 16 feb, 09:23, Eduardo Yáñez Parareda <eduardo.yanezNOS...@NOSPAMgmail.com> wrote: > > Encripta el .properties Mi duda es como hacer eso. ¿Existe un método inmediato?
Re: Almacenar contraseña
Author: Eduardo Yáñez Parareda
Date: Wed, 21 Feb 2007 17:48
Date: Wed, 21 Feb 2007 17:48
14 lines
1474 bytes
1474 bytes
Guevonaso wrote: > On 16 feb, 09:23, Eduardo Y��ez Parareda > <eduardo.yanezNOS...@NOSPAMgmail.com> wrote: >> Encripta el .properties > > Mi duda es como hacer eso. �Existe un m�todo inmediato? T� dec�as: "hasta ahora las contrase�as del usuario siempre las almacenaba encriptadas con MD5 o SHA" Pues cifra el fichero con MD5 o con lo que quieras, como hac�as antes con la contrase�a, pero en vez de la contrase�a, cifra todo el fichero.
Re: Almacenar contraseña
Author: Guevonaso
Date: Thu, 22 Feb 2007 09:36
Date: Thu, 22 Feb 2007 09:36
20 lines
2109 bytes
2109 bytes
On 21 feb, 18:48, Eduardo Yáñez Parareda <eduardo.yanezNOS...@NOSPAMgmail.com> wrote: > Guevonaso wrote: > > On 16 feb, 09:23, Eduardo Yáñez Parareda > > <eduardo.yanezNOS...@NOSPAMgmail.com> wrote: > >> Encripta el .properties > > > Mi duda es como hacer eso. ¿Existe un método inmediato? > > Tú decías: > > "hasta ahora las contraseñas del usuario siempre las > almacenaba encriptadas con MD5 o SHA" > > Pues cifra el fichero con MD5 o con lo que quieras, como hacías antes con la contraseña, pero en vez de la contraseña, > cifra todo el fichero. Ya... y como recupero los datos ? MD5 es de un solo sentido, no puedo recuperar la información una vez cifrada.
Re: Almacenar contraseña
Author: Eduardo Yáñez Parareda
Date: Thu, 22 Feb 2007 11:24
Date: Thu, 22 Feb 2007 11:24
5 lines
1333 bytes
1333 bytes
> Ya... y como recupero los datos ? MD5 es de un solo sentido, no puedo > recuperar la informaci�n una vez cifrada. Ops!, perd�n, no me hab�a dado cuenta de eso. Usa un algoritmo sim�trico como el 3DES u otro parecido. O cr�ate t� el modo de cifrado...
Re: Almacenar contraseña
Author: Eduardo Yáñez Parareda
Date: Thu, 22 Feb 2007 11:38
Date: Thu, 22 Feb 2007 11:38
73 lines
3651 bytes
3651 bytes
Ejemplo de Google de cifrado con DES....
public class DesEncrypter {
Cipher ecipher;
Cipher dcipher;
DesEncrypter(SecretKey key) {
try {
ecipher = Cipher.getInstance("DES");
dcipher = Cipher.getInstance("DES");
ecipher.init(Cipher.ENCRYPT_MODE, key);
dcipher.init(Cipher.DECRYPT_MODE, key);
} catch (javax.crypto.NoSuchPaddingException e) {
} catch (java.security.NoSuchAlgorithmException e) {
} catch (java.security.InvalidKeyException e) {
}
}
public String encrypt(String str) {
try {
// Encode the string into bytes using utf-8
byte[] utf8 = str.getBytes("UTF8");
// Encrypt
byte[] enc = ecipher.doFinal(utf8);
// Encode bytes to base64 to get a string
return new sun.misc.BASE64Encoder().encode(enc);
} catch (javax.crypto.BadPaddingException e) {
} catch (IllegalBlockSizeException e) {
} catch (UnsupportedEncodingException e) {
} catch (java.io.IOException e) {
}
return null;
}
public String decrypt(String str) {
try {
// Decode base64 to get bytes
byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);
// Decrypt
byte[] utf8 = dcipher.doFinal(dec);
// Decode using utf-8
return new String(utf8, "UTF8");
} catch (javax.crypto.BadPaddingException e) {
} catch (IllegalBlockSizeException e) {
} catch (UnsupportedEncodingException e) {
} catch (java.io.IOException e) {
}
return null;
}
}
Here's an example that uses the class:
try {
// Generate a temporary key. In practice, you would save this key.
// See also e464 Encrypting with DES Using a Pass Phrase.
SecretKey key = KeyGenerator.getInstance("DES").generateKey();
// Create encrypter/decrypter class
DesEncrypter encrypter = new DesEncrypter(key);
// Encrypt
String encrypted = encrypter.encrypt("Don't tell anybody!");
// Decrypt
String decrypted = encrypter.decrypt(encrypted);
} catch (Exception e) {
}
Re: Almacenar contraseña
Author: Guevonaso
Date: Thu, 01 Mar 2007 15:12
Date: Thu, 01 Mar 2007 15:12
18 lines
2041 bytes
2041 bytes
On 22 feb, 12:38, Eduardo Yáñez Parareda
<eduardo.yanezNOS...@NOSPAMgmail.com> wrote:
> Ejemplo de Google de cifrado con DES....
>
Muchas gracias eduardo, una solucion muy simple y excelente. Pero
ahora tengo la duda de ¿que hago con la contraseña generada? ¿La
guardo tambien?
Estaba pensando en usar una constante o algo asi en lugar de :
SecretKey key = KeyGenerator.getInstance("DES").generateKey();
, pero ¿que me aconsejas?
Muchas gracias otra vez.
Fernando.
Re: Almacenar contraseña
Author: Eduardo Yáñez Parareda
Date: Thu, 01 Mar 2007 15:20
Date: Thu, 01 Mar 2007 15:20
15 lines
2029 bytes
2029 bytes
> Estaba pensando en usar una constante o algo asi en lugar de :
>
> SecretKey key = KeyGenerator.getInstance("DES").generateKey();
>
> , pero �que me aconsejas?
La gente suele dejar la clave entro del mimo c�digo, con una constante, o
la guarda en un fichero. Pero claro, si la guardas en un fichero, que no se llame
clave.properties :). Lo mismo te digo para la constante.
Ambas opciones son v�lidas.
Teni�ndolo en un fichero, o en BBDD, puedes, con otro programa externo, volver a cifrar con
una clave distinta cada cierto tiempo, sin necesidad de recompilar el c�digo. Todo depende
del grado de seguridad, y de la gente que tenga acceso al c�digo, a la m�quina donde est� instalado,
o a la BBDD si has optado por esta �ltima opci�n.
Re: Almacenar contraseña
Author: Guevonaso
Date: Thu, 01 Mar 2007 15:23
Date: Thu, 01 Mar 2007 15:23
26 lines
2667 bytes
2667 bytes
On 1 mar, 16:20, Eduardo Yáñez Parareda
<eduardo.yanezNOS...@NOSPAMgmail.com> wrote:
> > Estaba pensando en usar una constante o algo asi en lugar de :
>
> > SecretKey key = KeyGenerator.getInstance("DES").generateKey();
>
> > , pero ¿que me aconsejas?
>
> La gente suele dejar la clave entro del mimo código, con una constante, o
> la guarda en un fichero. Pero claro, si la guardas en un fichero, que no se llame
> clave.properties :). Lo mismo te digo para la constante.
> Ambas opciones son válidas.
> Teniéndolo en un fichero, o en BBDD, puedes, con otro programa externo, volver a cifrar con
> una clave distinta cada cierto tiempo, sin necesidad de recompilar el código. Todo depende
> del grado de seguridad, y de la gente que tenga acceso al código, a la máquina donde está instalado,
> o a la BBDD si has optado por esta última opción.
OK, cambiaré "claveSecreta" por "sk" o algo más rebuscado como
"tonteria" :)
Muchas gracias otra vez, eres un fiera.
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads