java - Proteger contraseña incorporada
security passwords (6)
Tengo un archivo de propiedades en java, en el que almaceno toda la información de mi aplicación, como el nombre del archivo de la imagen del logotipo, el nombre de la base de datos, el usuario de la base de datos y la contraseña de la base de datos.
Puedo almacenar la contraseña encriptada en el archivo de propiedades.
Sin embargo, la clave o frase de contraseña puede leerse desde el contenedor utilizando un decompilador.
¿Hay alguna forma de almacenar el paso de db en un archivo de propiedades de forma segura?
¿No podría hacer que la aplicación se ponga en contacto con un servidor a través de https y descargue la contraseña, después de autenticarse de alguna manera, por supuesto?
Además de encriptar las contraseñas como se describe arriba, coloque las contraseñas en un archivo de propiedades separado y en la implementación trate de darle a este archivo los permisos más bloqueados posibles.
Por ejemplo, si su servidor de aplicaciones se ejecuta en Linux / Unix como root
entonces convierta el archivo de propiedades de contraseñas propiedad de la root
con los permisos 400 / -r--------
.
Almacena un hash SHA1 de la contraseña en su archivo de propiedades. Luego, cuando valide la contraseña de un usuario, compruebe su intento de inicio de sesión y asegúrese de que los dos hashes coincidan.
Este es el código que copiará algunos bytes para usted. Puedes fácilmente ger bytes desde una Cadena usando el método getBytes()
.
/**
* Returns the hash value of the given chars
*
* Uses the default hash algorithm described above
*
* @param in
* the byte[] to hash
* @return a byte[] of hashed values
*/
public static byte[] getHashedBytes(byte[] in)
{
MessageDigest msg;
try
{
msg = MessageDigest.getInstance(hashingAlgorithmUsed);
}
catch (NoSuchAlgorithmException e)
{
throw new AssertionError("Someone chose to use a hashing algorithm that doesn''t exist. Epic fail, go change it in the Util file. SHA(1) or MD5");
}
msg.update(in);
return msg.digest();
}
Hay varias formas de gestionar esto. Si puede encontrar la forma de que un usuario proporcione una contraseña para un almacén de claves cuando se inicia la aplicación, la forma más adecuada sería encriptar todos los valores usando una clave, y almacenar esta clave en el almacén de claves. La interfaz de línea de comandos para el almacén de claves es mediante el uso de keytool. Sin embargo, JSE también tiene API para acceder mediante programación al almacén de claves.
Si no tiene la posibilidad de que un usuario proporcione manualmente una contraseña al almacén de claves durante el inicio (por ejemplo, para una aplicación web), una forma de hacerlo es escribir una rutina de ofuscación excepcionalmente compleja que pueda ofuscar la clave y almacenarla en un archivo de propiedad también. Cosas importantes para recordar es que la lógica de ofuscación y desofuscación debe ser de varias capas (podría involucrar cifrado, codificación, introducción de caracteres espurios, etc.) y debería tener al menos una clave que podría ocultarse en otras clases de la aplicación. usando nombres no intuitivos. Este no es un mecanismo completamente seguro ya que alguien con un descompilador y una buena cantidad de tiempo e inteligencia aún pueden solucionarlo, pero es el único que conozco que no requiere que se rompa en código nativo (es decir, no fácilmente descompilable) .
No no hay. Incluso si lo encriptas, alguien descompilará el código que lo descifra.
Puede crear un archivo de propiedades separado (fuera del contenedor) para las contraseñas (ya sea una contraseña directa de DB o una frase de contraseña clave) y no incluir ese archivo de propiedades con la distribución. O puede hacer que el servidor solo acepte ese inicio de sesión desde una máquina específica para que se requiera suplantación.