25

What would be the recommended way for storing passwords in a Java desktop application?

I want the user to have the ability to enter the credencials only once and not be prompted again.

On personal projects I've been using the Preferences API, but I'm assuming this is no different than storing it in plain text (security wise).

Many thanks

EDIT:

Many thanks for your suggestions. There seems to be some confusion, no doubt because I might have not made the question very clear...

I'll give an hypotetical scenario:

Say I'm creating a simple front-end for a remote database which creates a connection string with username/password. Normally the user would be prompted to enter the username/password combination each time the application starts.

What would be the best way to store that password in the user's machine, without the need to re-enter it (connecting automatically upon application start).

A kind of "remember me" functionality (which I know in itself is not a very good practice...)

EDIT2:

Thanks for your answers everyone. Paŭlo Ebermann's was very informative about the problems at hand and Chris Smith's link was interesting, but I've accepted JVerstry's one, as keystores might be the route I'm taking.

Rui Vieira
  • 5,025
  • 5
  • 39
  • 53
  • 2
    Take a look at this question: http://stackoverflow.com/q/6592010/313205 – Marcelo Aug 10 '11 at 20:59
  • 3
    Please don't go to Marcelo's link. It's full of bad advice. Check the answer and read codahale's article. What was good advice 10 years ago has been made insecure in the last 5 years because we can brute force these algorithms easily with a small investment in computer hardware. SHA1, MD5, and passwords under 8 characters with all symbols (a-z,A-Z,0-9,special characters) can easily be broken. – chubbsondubs Aug 10 '11 at 21:32
  • +1 for not SHA1/MD5. As I posted below, which some eejit took offense to. – Deleted Aug 10 '11 at 21:40
  • Are you talking about passwording your own application or storing the passwords to external systems, like the database or a web service? – Affe Aug 10 '11 at 21:56
  • You first need to describe who you want to protect against. – CodesInChaos Aug 10 '11 at 22:47
  • @CodesInChaos "*[Everyone who isn't us is an enemy.](https://www.youtube.com/watch?v=b1G6bVQ4Veg)*" - any program but his application should not be able to get the password. – Tomáš Zato - Reinstate Monica Mar 18 '15 at 07:35

3 Answers3

12

You can use a local keystore where you could put passwords instead of secret keys.

Answer to edit:

Keystores are a perfect fit for your need. If you want extra protection, you could ask the user for one password to access all passwords when the user starts the application. Then, you could protect stored database password with a simple salt-and-stretch method (to generate an encryption key) using the one password that was used when starting the application.

BSMP
  • 3,862
  • 8
  • 31
  • 41
Jérôme Verstrynge
  • 51,859
  • 84
  • 263
  • 429
  • 8
    This question has 8000 views. Your answer has 6 lines (originally had just one) on a complex security topic. Are you serious? Answers on questions like this tend to have lot more upvotes (and lines). What's keystore? How is it used? Is it a Java thing or OS thing? I wish I could downvote for every question your "*answer*" raised. – Tomáš Zato - Reinstate Monica Mar 18 '15 at 07:30
  • 2
    @TomášZato This is a Java question, keystore's are a core feature, of Java SSE (Secure Socket Extension). For all of the views this question has, this answer doesn't have very many upvotes. – Raystorm Apr 27 '15 at 18:30
  • @Raystorm "*For all of the views this question has, this answer doesn't have very many upvotes.*" - That's what I was pointing out. – Tomáš Zato - Reinstate Monica Apr 27 '15 at 19:05
  • Yes, this answer could have a lot more details and be a lot more useful. ;) – Geoffrey Wiseman Aug 02 '16 at 15:36
5

There is no way to store something on a computer in a way that your Java program can retrieve it (without the user entering some password), but no other program (running in the same user's account) on this computer can retrieve it.

You can try to encrypt it somehow and hide the decryption algorithm together with the decryption key in your program (white-box cryptography), but then the attacker just needs to run your program in a debugger to let it decrypt the data.

You could use the system's permission system, but this will usually not help if the attacker is some program running in the same user account as your Java program (and would help even less if the attacker has root access).

The best bet would be to store the password on a USB memory and tell the user to take it out when you are done using it, but if the attacking program is running and observing while you are reading the secret from the stick, even this does not help.

Paŭlo Ebermann
  • 68,531
  • 18
  • 138
  • 203
  • yes but the decryption algorithm could be tied to the time on the internet which would be a huge pain to figure out. – Solomon P Byer Jul 03 '15 at 14:40
  • Using the system's permissions may well help if the attacker doesn't have root access. – Brian McCutchon Feb 01 '17 at 21:54
  • @BrianMcCutchon if the attacker also runs in the same user account as your Java program, both have the same privileges, and can access the same files. Of course, a root attacker can access anyone's files. – Paŭlo Ebermann Feb 02 '17 at 15:51
  • @PaŭloEbermann Not if the OS controls which applications can access passwords, as MacOS keychain does, for instance. In MacOS keychain, an application can use passwords it creates and passwords that the user explicitly gives it access to. See here: https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/02concepts/concepts.html – Brian McCutchon Feb 03 '17 at 00:10
  • @BrianMcCutchon Okay, I don't know anything about how MacOS works ... can you register a Java program as an "application" (instead of just using the "java" interpreter as the app)? – Paŭlo Ebermann Feb 04 '17 at 20:55
  • You can totally make a Java Mac application using one of the app bundler tools available for Maven or Ant. – Brian McCutchon Feb 05 '17 at 04:44
-3

Regardless of the language, I think this applies: http://codahale.com/how-to-safely-store-a-password/

In summary, use a bCrypt hash function.

The preferences API is implementation dependent from memory so you will be at the mercy of the JVM vendor. If it's a Sun/Oracle JVM, it's trivial to get at the data. If you hash it and enforce a decent password policy however, it will be very safe. The original password will be very hard to determine.

Deleted
  • 4,368
  • 1
  • 18
  • 17
  • 3
    hashing a password does not allow you to retrieve it. – Jérôme Verstrynge Aug 10 '11 at 21:31
  • 1
    Err why do you want to retrieve the password? That's just crazy talk. – Deleted Aug 10 '11 at 21:39
  • "I want the user to have the ability to enter the credencials only once and not be prompted again." -> Meaning the password is going to be reused. – Jérôme Verstrynge Aug 10 '11 at 21:47
  • 3
    I think the unclear point is that it seems like the OP actually wants to store the password to some third party system, e.g., his database connection string securely, so that he can programmatically submit it later. It is not assumed that the external system has an API that accepts an already hashed password via arbitrary algorithm! – Affe Aug 10 '11 at 21:54
  • 1
    @JVerstry: No - that's not right. The hashed password is reused, not the unhashed password. You hash it up front and then compare the hash every time you need the credentials verified. If you need to talk to providers which support different hash algorithms, you store ALL variants up front that your providers or services require(SHA1, MD5, bCrypt etc). If they talk plain text passwords, then there are some serious problems. – Deleted Aug 10 '11 at 21:55
  • @Chris The question is: "What would be the recommended way for storing passwords in a Java desktop application?" It is not about remote services or providers. – Jérôme Verstrynge Aug 10 '11 at 22:09
  • @JVerstry: which I've answered. – Deleted Aug 10 '11 at 22:15
  • 7
    @Chris If you store hashes of passwords, it does not solve the problem, especially if you are going to use them. The hashes are not protected themselves. With all due respect, your proposed solution is not a solution. You are missing the point. – Jérôme Verstrynge Aug 10 '11 at 22:26
  • 1
    Storing anything that can be directly used to authenticate will allow attackers to log in in your place. – Paŭlo Ebermann Aug 10 '11 at 23:40
  • If that is the case, and it is a problem, then you should store the hashed password in volatile storage (memory). If it is an attack vector, then don't store the password. I think people are making this problem way larger than it is :) – Deleted Aug 11 '11 at 08:11
  • 3
    Storing hashed passwords works if your app is the only thing needing authenticating (because you can just store/compare the hashed passwords, very secure). However, if the passwords are for another system then you need to store the raw password. A good example would be an FTP client: it needs to store your raw passwords because that's what it needs to give to the server. – ryvantage Nov 15 '13 at 19:42