views:

534

answers:

7

I have a properties file in java, in wich i store all information of my app, like logo image filename, database name,database user and database password.
I can store the password encrypted on the properties file.
But, the key or passphrase can be read out of the jar using a decompiler.
Is there a way to store the db pass in a properties file securely?

A: 

Don't store the password, store a cryptographic hash of it.

moonshadow
And then salt it to make dictionary attacks against it that little bit harder :)Also try to avoid using md5 hashes.
freespace
Storing a hash only allows you to verify a passowrd, it doesn't allow you to use the password to access anything else, like a database.
Dave L.
This doesn't resolve his problem
Allain Lalonde
It actually does...
jjnguy
The problem is the original question wasn't clear how this password was being used. I assumed that the password was being used to access an external database, not to verify a user entered password. I've since deleted my reply.
smo
+1  A: 

No there is not. Even if you encrypt it, somebody will decompile the code that decrypts it.

florin
If you give someone the key and the lock, they are able to duplicate the key and access the lock without the key you gave them originally. Unless you do not provide the key there is no way to prevent them from getting at it. It's the fundamental flaw with DRM as well.
Adam Davis
+2  A: 

There are multiple ways to manage this. If you can figure out a way to have a user provide a password for a keystore when the application starts up the most appropriate way would be to encrypt all the values using a key, and store this key in the keystore. The command line interface to the keystore is by using keytool. However JSE has APIs to programmatically access the keystore as well.

If you do not have an ability to have a user manually provide a password to the keystore on startup (say for a web application), one way to do it is to write an exceptionally complex obfuscation routine which can obfuscate the key and store it in a property file as well. Important things to remember is that the obfuscation and deobfuscation logic should be multi layered (could involve scrambling, encoding, introduction of spurious characters etc. etc.) and should itself have at least one key which could be hidden away in other classes in the application using non intuitive names. This is not a fully safe mechanism since someone with a decompiler and a fair amount of time and intelligence can still work around it but is the only one I know of which does not require you to break into native (ie. non easily decompilable) code.

Dhananjay Nene
A: 

You could make a separate properties file (outside the jar) for passwords (either direct DB password or or key passphrase) and not include that properties file with the distribution. Or you might be able to make the server only accept that login from a specific machine so that spoofing would be required.

James A. N. Stauffer
+3  A: 

You store a SHA1 hash of the password in your properties file. Then when you validate a users password, you hash their login attempt and make sure that the two hashes match.

This is the code that will hash some bytes for you. You can easily ger bytes from a String using the getBytes() method.

/**
     * 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();
    }
jjnguy
Good answer, but not to his question.
Allain Lalonde
I guess I don't fully understand the question then.
jjnguy
He wants to store the username and password that the application will use to connect to the database. So he needs to be able to covert it back to plaintext before he connects to the database.
bmatthews68
Actually, the database shoud have the hashed version of the password stored in it. The only time a password should ever be plain text is when the user types it and when the database admin first sets it up.
jjnguy
A: 

In addition to encrypting the passwords as described above put any passwords in separate properties file and on deployment try to give this file the most locked down permissions possible.

For example, if your Application Server runs on Linux/Unix as root then make the password properties file owned by root with 400/-r-------- permissions.

Dave Webb
A: 

Couldn't you have the app contact a server over https and download the password, after authenticating in some way of course?

Allain Lalonde