What is the best practice for securely storing passwords in Java
Asked Answered
W

3

28

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.

Weathercock answered 10/8, 2011 at 20:56 Comment(6)
Take a look at this question: https://mcmap.net/q/388951/-encrypt-and-decrypt-a-password-in-java-closed/313205Galagalactagogue
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.Chastise
+1 for not SHA1/MD5. As I posted below, which some eejit took offense to.Gambrill
Are you talking about passwording your own application or storing the passwords to external systems, like the database or a web service?Greenquist
You first need to describe who you want to protect against.Bereft
@Bereft "Everyone who isn't us is an enemy." - any program but his application should not be able to get the password.Dorset
S
14

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.

Smoothshaven answered 10/8, 2011 at 21:30 Comment(4)
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.Dorset
@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.Sanjuanitasank
@Sanjuanitasank "For all of the views this question has, this answer doesn't have very many upvotes." - That's what I was pointing out.Dorset
Yes, this answer could have a lot more details and be a lot more useful. ;)Lamond
O
6

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.

Okechuku answered 10/8, 2011 at 23:46 Comment(6)
yes but the decryption algorithm could be tied to the time on the internet which would be a huge pain to figure out.Marqueritemarques
Using the system's permissions may well help if the attacker doesn't have root access.Neoma
@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.Kurd
@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: developer.apple.com/library/content/documentation/Security/…Neoma
@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)?Kurd
You can totally make a Java Mac application using one of the app bundler tools available for Maven or Ant.Neoma
G
-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.

Gambrill answered 10/8, 2011 at 21:15 Comment(11)
hashing a password does not allow you to retrieve it.Enlace
Err why do you want to retrieve the password? That's just crazy talk.Gambrill
"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.Enlace
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!Greenquist
@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.Gambrill
@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.Enlace
@JVerstry: which I've answered.Gambrill
@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.Enlace
Storing anything that can be directly used to authenticate will allow attackers to log in in your place.Kurd
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 :)Gambrill
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.Enclasp

© 2022 - 2024 — McMap. All rights reserved.