1

How to store a passphrase with a Java application that periodically needs access to its plaintext form? It is a strange situation, but I am wedged in it. If providing a decent security mechanism is impossible, any tips on deterring script-kiddies?

Elaboration on my situation (it rhymes):

It's an inconvenient (read "horrible") situation where the application will be accessing a remote http (not https) service, passing a login/password in plaintext, a few times a week. Yes, ideally I would change service, but I can't do that. Given that, my question is on how to store the login, which the application needs to be able to access in plaintext/unencrypted form. Is there a more secure or at least script-kiddies deterrent solution than just hardcoding the plain values?

Elaboration 2:

This is a server app. I might have the option to host it on a Java EE app server, I am not aware of benefits it provides though. At the same time I am equally interested in how I could deal with this outside a JEE app sever.

6
  • What do you mean by "periodically needs its plaintext form"? Does the application need to access it, or does the user enter it on a regular basis? You need to elaborate more on the use case here. Jan 15 '14 at 9:37
  • @KarthikRangarajan the application needs access to it periodically.
    – user37175
    Jan 15 '14 at 9:48
  • You will need to elaborate on your problem because, right now, it's really not clear what your situation is and what you want to achieve (at least to me)
    – Stephane
    Jan 15 '14 at 10:12
  • @Stephane I have appended more information to my question.
    – user37175
    Jan 15 '14 at 10:34
  • 2
    You still need to provide more information. Is the app in question a desktop app or something that will be running in a JEE app server? App servers do provide a fairly robust means of storing such passwords.
    – user10211
    Jan 15 '14 at 11:36
2

First, the login should be issued per-client, so it can be changed if leaked, or cancelled when a client's access to the service is revoked. This reduces the consequences of loss of the password to the smallest size, instead of losing everything when one client is compromised or goes rogue.

Once you have done that, your problem is simply to store a password which is used for this one client with this one service. This is a well-known problem with well-known solutions. Essentially, you should assume that the operating system is secure. (If it is not you have bigger problems.) So save it into a file, the registry etc, and protect it with an ACL. If you wish you can add obfuscation on top of that, or use CryptProtectData or similar, which can provide some protection against unsophisticated attackers.

But the bottom line is you need to accept that issuing, revoking, and resetting credentials is going to be a normal part of your operation. You will also want to monitor usage of the service so you can detect when credentials have leaked.

1

This is difficult to achieve without leaving a reasonably significant level of risk (if the host were to be compromised in some way), although can be mitigated to some degree.

The HTTP credentials should be encrypted via a strong (and well established) symmetric algorithm, which would require a password for decryption. Since it will need to decrypt the password without an operator being present, the key will need to be available somewhere - which is the weakness of this method. I would advise against hard-coding any of these details, since all could be revealed if someone got their hands on the application files. Instead, I would recommend that the user is asked for the HTTP credentials and an encryption password during setup / first use. The application would then ask for the encryption password each time it is started, which will be stored in memory until the application process ends. This would require an operator during the first install and for each reboot etc.

(N.b. It is recommended that character arrays are used for password variables rather than strings due to garbage collection in Java. See here: https://stackoverflow.com/a/12981202/3177084)

However, a more convenient solution - which relies on the application being used solely on Windows, but essentially manages all of the above for you - would be to utilise DPAPI. This basically encrypts and stores credentials using the Windows account details, so the application should be able to retrieve the HTTP credentials as long as its being executed by a user who has stored them via DPAPI. This has similar weaknesses to the home-grown solution above, but avoids the pitfalls of implementing your own crypto-system.

1

Apparently, your main vulnerability in this model is the network: spending time and money in trying to store data that will travel in cleartext is a waste of time (and money).

Typically, you will attempt to solve that kind of problem by adding a security layer around the vulnerable part: if you can't get the remote system to use HTTPS, then use a VPN that ends as close as possible to the target server (because anyone having access to the network between that VPN endpoint and the HTTP server will be able to obtain the cleartext data).

Another option is to place both systems in the same hardened network. (This usually only makes sense if you already have such a network available).

Once you have secured the network, then you can think about securing these keys (although, in your case, it might still be pointless if the remote system doesn't treat this key securely).

-1

Encode it in Base64 keep the result in a variable and decode it when needed. That will keep script-kiddies away, but not rest.

8
  • I meant ecode it OUTSIDE your program. Take the string that result from the encryption and put that string in a variable in your program. You will need either to find a function to decode it or just make your own.
    – YoMismo
    Jan 15 '14 at 9:43
  • 1
    You didn't take the time to understand what he wants to do, against what he wants to protect his data and you rushed to gave him one of the worse advise you can give to an application developer: the only thing base64 will protect you from is 7bit ASCII systems.
    – Stephane
    Jan 15 '14 at 10:15
  • Really? What I understood is that he needs to keep in his code a passphrase which has to be used in specific points of the code, and he doesn't want that passfrase to be in plain text inside the code. It's the OP who has to clear this. In case I am right, you can't acomplish that at all without interaction introducing a password to decrypt something, which is not what I understood he wants. So, knowing you can't solve that problem, and having he said he wants script-kiddies away, base64 is a solution for that, you can even make your own base64, but I see no need for that to avoid SC.
    – YoMismo
    Jan 15 '14 at 10:40
  • Looks like I was right. There is no solution for his problem, someone interested and with access to the executable will be able to access the passfrase, aside from the fact that any machine inbetween will have access to the plain text sent via http. Why trying to protect the passphrase in your machine when those on the Internet may be able to see it whenever you send it to the other machine?
    – YoMismo
    Jan 15 '14 at 10:51
  • You do not know that. You have no idea what his environment is and what is actually needed. You don't even know what he wants to protect these key phrases against!
    – Stephane
    Jan 15 '14 at 15:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy