70

What is the best way to save user settings in java desktop app securely? For example If I want to save an Ftp account settings what is the best way to do that?

Thanks

Feras Odeh
  • 9,136
  • 20
  • 77
  • 121

3 Answers3

58

The Preferences API is a nice way to store user and system preferences. If you want to store passwords, you'll have to encrypt them. Here is a nice article that can get you started.

Encrypted Preferences in Java

Giorgos Dimtsas
  • 12,019
  • 3
  • 29
  • 40
  • 14
    Where shall we store the required key? – Cheok Yan Cheng Sep 24 '10 at 13:22
  • 6
    Nice intro tutorial here: http://www.mkyong.com/java/java-properties-file-examples/ – james.garriss May 29 '13 at 11:41
  • I want to note that on Windows you might have to change the registry if you are using Preferences. For a normal user of your application, this might be a blocker (no-go!). – El Mac Apr 06 '16 at 11:29
  • @ElMac: I guess you refer to the infamous `WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0x80000002. Windows RegCreateKeyEx(...) returned error code 5` warning? Which has led users to believe that they need to use `regedit` to create a new Win Registry key (because then this warning goes away). This is actually a [bug in Java itself](http://stackoverflow.com/a/41151051/1504556). You are not meant to have to do this. It is a result of the bug. – peterh Mar 05 '17 at 07:44
26

I usually store in user data directory, with sub directories of application name followed by application version.

public static String getUserDataDirectory() {
    return System.getProperty("user.home") + File.separator + ".jstock" + File.separator + getApplicationVersionString() + File.separator;
}

I had been using the following code for 3 years. This method works quite well either in Windows, Linux or Mac.

Please note that, in Windows, never store it in Program Files, as UAC in Windows Vista or newer may give you a lot of trouble.

Remember put a dot in-front of your application name, so that it will become a hidden folder in Linux.

Good thing by using this methology is that, you are not limited your self in storing primitive value only. Instead, you may save the entire object state to the disk by using xstream

For example :

public static boolean toXML(Object object, File file) {
    XStream xStream = new XStream();
    OutputStream outputStream = null;
    Writer writer = null;

    try {
        outputStream = new FileOutputStream(file);
        writer = new OutputStreamWriter(outputStream, Charset.forName("UTF-8"));
        xStream.toXML(object, writer);
    }
    catch (Exception exp) {
        log.error(null, exp);
        return false;
    }
    finally {
        close(writer);
        close(outputStream);
    }

    return true;
} 
Cheok Yan Cheng
  • 47,586
  • 132
  • 466
  • 875
  • But is this secure? Are you storing passwords in plain-text? – djna Sep 24 '10 at 06:47
  • 1
    There's a case for storing passwords in plain text, as opposed to simply obfuscating them - obfuscation gives a false sense of safety. See for example http://developer.pidgin.im/wiki/PlainTextPasswords – gustafc Sep 24 '10 at 06:57
  • Before I store a password, I will use http://www.jasypt.org/ to perform encryption. Currently, I hard code my encryption key in my application. I once thinking to let user specific the key. However, that may stop average user from using my app as it is kind to hard to explain what key is. Hence, I give up the idea. So far, I receive no complain on security issue by doing so. – Cheok Yan Cheng Sep 24 '10 at 07:09
  • 6
    So anyone with a copy of your program can use anybody's key file? Lack of compalints doesn't make it secure. A person whose password is compromised may not even be aware of the fact. Sure this works and with properly protected machines it's quite low risk, but in fact the encryption buys very little. In effect your applciation is the key, so that's what needs to be protected. – djna Sep 24 '10 at 11:17
  • 4
    I think this is a security threat.As a cracker can get the hard coded password by decompiling your Java code. – Feras Odeh Sep 25 '10 at 04:36
  • That's not where you store user or application data on Windows. – Cypher Dec 12 '18 at 22:54
13

Storing a single password securely is quite difficult. Suppose you encrypt the password using some secret key. Then when your applciation starts again it needs that secret key, where does it get that from?

If it asks the user then he might as well just enter the ftp password which you stored in the first place. If it reads the secret key from somewhere then you need to secure the secret key, and we're back where we started.

If you are keeping several passwords then asking the user for a single password to some "vault" may be much friendlier, but you then get into all the hassle of dealing with expired passwords.

There are products available to deal with this wort of stuff, if you have a serious need then you probably need to investigate them.

djna
  • 54,992
  • 14
  • 74
  • 117