una - programar usuario y contraseña en java
Java: cifra/descifra el nombre de usuario y la contraseña de un archivo de configuración (2)
Estamos ocupados desarrollando un servicio web Java para un cliente. Hay dos opciones posibles:
Almacene el nombre de usuario / contraseña encriptados en el cliente del servicio web. Leer desde una configuración archivo en el lado del cliente, descifrar y enviar.
Almacene el nombre de usuario / contraseña encriptados en el servidor web. Leer desde una configuración archivo en el servidor web, descifrar y utilizar en el servicio web.
El nombre de usuario / contraseña es utilizado por el servicio web para acceder a una aplicación de terceros.
El cliente ya tiene clases que proporcionan esta funcionalidad, pero este enfoque implica enviar el nombre de usuario / contraseña en forma clara (aunque dentro de la intranet). Preferirían almacenar la información. dentro del servicio web pero realmente no quieren pagar por algo que ya tienen. (La seguridad no es una gran consideración porque solo está dentro de su intranet).
Entonces, necesitamos algo rápido y fácil en Java.
¿Alguna recomendación?
El servidor es Tomkat 5.5. El servicio web es Axis2.
- ¿Qué paquete de cifrado / descifrado deberíamos usar?
- ¿Qué tal una tienda clave?
- ¿Qué mecanismo de configuración deberíamos usar?
- ¿Será esto fácil de implementar?
Estar en la intranet ciertamente no justifica el rechazo de la seguridad. La mayoría del daño infligido a la información es por personas internas. Mire el valor de lo que se está protegiendo y preste la debida consideración a la seguridad.
Parece que hay una aplicación de terceros, para la cual tiene un conjunto de credenciales, y algunos clientes que efectivamente comparten esta identidad cuando usan la aplicación de terceros. Si ese es el caso, recomiendo el siguiente enfoque.
No distribuya la contraseña de terceros más allá de su servidor web.
La forma más segura de hacerlo es proporcionarlo a la aplicación web de forma interactiva. Esto podría ser ServletContextListener que solicita la contraseña cuando se inicia la aplicación, o una página en la aplicación para que un administrador pueda ingresarla a través de un formulario. La contraseña se almacena en ServletContext y se utiliza para autenticar solicitudes al servicio de terceros.
Un paso atrás en seguridad es almacenar la contraseña en el sistema de archivos del servidor para que solo pueda ser leída por el usuario que ejecuta el servidor. Esto depende de los permisos del sistema de archivos del servidor para la protección.
Intentar almacenar una forma encriptada de la contraseña, en el cliente o el servidor, es solo retroceder un paso. Caes en una regresión infinita cuando tratas de proteger un secreto con otro secreto.
Además, los clientes deben autenticarse en el servidor. Si el cliente es interactivo, solicite a los usuarios que ingresen una contraseña. El servidor puede decidir si ese usuario está autorizado para acceder al servicio de terceros. Si el cliente no es interactivo, la siguiente mejor seguridad es proteger la contraseña del cliente utilizando los permisos del sistema de archivos.
Para proteger las credenciales de los clientes, el canal entre el cliente y su servidor web debe estar protegido con SSL. Aquí, operar en una intranet es ventajoso, porque puede usar un certificado autofirmado en el servidor.
Si almacena contraseñas en un archivo, colóquelas en un archivo por sí mismas; hace que la necesidad de administrar permisos sea más llamativa y minimiza la necesidad de que muchos usuarios editen ese archivo y vean la contraseña.
Como entiendo de todos modos para llamar al servicio web de terceros, pasas la contraseña como texto sin formato y no se involucran certificados de seguridad.
Entonces, diría que el enfoque más fácil sería almacenar la contraseña en formato cifrado (a través del mecanismo de cifrado de Java) cuando la clave de cifrado / descifrado está apenas codificada en el código.
Definitivamente lo almacenaría en el lado del servidor (sistema de archivos o db) en lugar de distribuirlo y mantenerlo en los múltiples clientes.
Aquí es cómo eso podría funcionar con el cifrado "DES":
// only the first 8 Bytes of the constructor argument are used
// as material for generating the keySpec
DESKeySpec keySpec = new DESKeySpec("YourSecr".getBytes("UTF8"));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey key = keyFactory.generateSecret(keySpec);
sun.misc.BASE64Encoder base64encoder = new BASE64Encoder();
sun.misc.BASE64Decoder base64decoder = new BASE64Decoder();
.........
// ENCODE plainTextPassword String
byte[] cleartext = plainTextPassword.getBytes("UTF8");
Cipher cipher = Cipher.getInstance("DES"); // cipher is not thread safe
cipher.init(Cipher.ENCRYPT_MODE, key);
String encrypedPwd = base64encoder.encode(cipher.doFinal(cleartext));
// now you can store it
......
// DECODE encryptedPwd String
byte[] encrypedPwdBytes = base64decoder.decodeBuffer(encryptedPwd);
Cipher cipher = Cipher.getInstance("DES");// cipher is not thread safe
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] plainTextPwdBytes = (cipher.doFinal(encrypedPwdBytes));