6

Our web-based applications has user accounts tied down to users with the passwords specified during account creation. In the case of Java, how does one process the password securely, before persisting its hash in the database.

To be more specific, how does one ensure that the string holding the password is garbage collected within a sufficiently short interval of time ?

Vineet Reynolds
  • 76,006
  • 17
  • 150
  • 174
  • This might help for securing password during registration process.http://wheelersoftware.com/articles/spring-security-hash-salt-passwords.html – Dead Programmer Aug 19 '11 at 08:17

6 Answers6

6

If you have the possibility (may be difficult in web applications), it would be better to store passwords in character arrays than to store them in strings. If you finished storing the password you can overwrite it in memory by using Array.fill() and make the reference available for the garbage collector by discarding it:

Arrays.fill(password, ' ');
password = null;

I just noticed that nulling the password would be a bit paranoid but you can do if it reassures you :)

Markus
  • 1,772
  • 1
  • 12
  • 20
  • If this is possible in a web app - read the password from the servlet input stream into a byte array, and then fill the array with zeroes after persisting the password, then it should turn out to be a viable approach. The OWASP Java project uses this in an example, but not for persisting passwords. – Vineet Reynolds Mar 15 '09 at 18:36
  • 2
    Doesn't this require that the garbage collector doesn't compact the stack and thus leave a copy of the array elsewhere in memory? – Chris Chilvers Aug 11 '09 at 19:44
  • 1
    @KeeperOfTheSoul: Yes, eventually it depends on GC behavior. It also depends on whether the array will be serialized or not. All in all, I wished that Java had a SecureString class similar to the one in Microsoft .Net. – Vineet Reynolds Aug 29 '09 at 22:30
  • Does this solution secure the passwords by not allowing anybody to get the passwords via a memory dump? – Samitha Chathuranga Apr 18 '16 at 06:00
5

You do not use a String. You use a char[] and then overwrite the char[] when done.

There are absolutely no guarantees when it comes to garbage collection (aside from that the finalizer will run before the object is collected). The GC may never run, if it runs it may never GC the String that has the password in it.

TofuBeer
  • 60,850
  • 18
  • 118
  • 163
3

If you create the hash on the client side, there should be no need to think about this problem. The plain password is never submitted to the server.

Mork0075
  • 5,895
  • 4
  • 25
  • 24
  • Yes, that's a good approach, but then wouldn't that also leave attackers with the ability to study the hash algorithm in use ? Granted that it is security through obscurity in a way, but it does limit the amount of information available to the attacker on how passwords are stored. – Vineet Reynolds Mar 14 '09 at 17:24
  • That would be an option but couldn't an attacker intercept the client-generated hash, too and then just generate the same HTTP request again to login? – Markus Mar 14 '09 at 17:47
  • @Markus, HTTPS is always used, so the probability of a MITM attack is low or nill. – Vineet Reynolds Mar 14 '09 at 18:08
  • 2
    Why bothering with client-side encryption when HTTPS is used anyway? – Markus Mar 14 '09 at 18:18
  • @vineet: HTTPS is the safest , if using HTTP the solution by Mork is the best which is a challenge/reponse method without sending password, but there is man in the middle attack problem. – Dead Programmer Aug 19 '11 at 08:12
  • 2
    That way you only redefine what the plaintext password is. So you obviously need to hash again on the server, and your scheme didn't help with the OP's problem at all. – CodesInChaos May 19 '12 at 12:14
3

Two words: Local Scope. The declared variables for password processing need to have the absolute smallest scope possible.

Once the variables go out of scope, the objects are eligible for garbage collection.

Often, you're picking things out of a request. You want a very, very small transaction that accepts the request, hashes the password, persists it and redirects. The page to which you redirect can then fetch content and do all the "other" processing that is part of your application.

S.Lott
  • 384,516
  • 81
  • 508
  • 779
1

There is no way to guarantee that clear text passwords are removed from memory in Java.

However a hacker doesn't need access to the memory of a program to get clear text passwords. There are much simpler ways (such as sniffing the packets) so it is highly unlikely anyone would rely on this approach.

The best approach is to have the client encrypt the password as @Mork0075 suggests. However, while it means you cannot easily get the password, a program can still get the encrypted version of passwords and so pretend to be a user. A way around this is to encrypt the whole connection using SSL.

All this is rather academic, as the simplest approach for a hacker is to monitor the packets to the database and get the password for your database. I suspect direct access to your database is more concerning... or perhaps its isn't. ;)

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • I'm looking at protecting the passwords, not because an attacker would attempt this approach - the box has been compromised if he's able to peek into memory, so there are bigger things to worry about. I'm seeking to prevent passwords from appearing in a Java heap dump obtained for diagnosis. – Vineet Reynolds Mar 14 '09 at 17:22
0

Use a password challenge:

  1. Server chooses a challenge value and sends it to the Client
  2. Server performs a 1-way translation with the password and the challenge, ex. MD5(CONCAT(challenge, password)) and assigns it to the session.
  3. Plain-text password is now out-of-scope and ready for garbage collection.
  4. Client also performs the same translation and sends the result to the Server.
  5. If Server and Client choose the same final value, the client is authenticated.

This method prevents replay attacks, but requires the challenge value to be very unpredictable (random) and not often reused (long).

The plain-text password is only in scope during the handling of the initial connection request - not during authentication. It doesn't matter how long the 1-way translation result is in scope (not garbage collected) because it has little replay value.

Andy
  • 11,215
  • 5
  • 31
  • 33
  • That would work fine for the login process but the author asked for registering an account, so you have to store an hash value in a database, too. This hash can't be generated through a challenge value since it couldn't be restored at login. – Markus Mar 14 '09 at 17:52