Can someone steal a password from a Java application? - java

Suppose there is a String variable that holds a plain text password.
Is there any possibility of reading this password using a memory dump. (Suppose using cheat engine.) I am puzzled with this JVM thing. Does JVM provide some sort of protection against this. If no what are the practices that I need to use to avoid such "stealing".
A practical threat would be a Trojan; that sends the segments of the memory dump to an external party.

As already noted, yes, anybody can extract the password, in various ways. Encrypting the password won't really help -- if it's decrypted by the application, then the decrypted form will also be present at some point, plus the decryption key (or code) itself becomes a vulnerability. If it's sent somewhere else in encrypted form, then just knowing the encrypted form is enough to spoof the transaction, so that doesn't help much either.
Basically, as long as the "attacker" is also the "sender", you're eventually going to get cracked -- this is why the music and video industries can't get DRM to work.
I suggest you pick up a copy of Applied Cryptography and read the first section, "Cryptographic Protocols". Even without getting into the mathematics of the actual crypto, this will give you a good overview of all sorts of design patterns in this area.

If you keep the password in plain text in your application then someone can read it by playing with memory dumps regardless of the language or runtime you use.
To reduce the chance of this happening only keep the password in plain text when you really need to, then dump or encrypt it. One thing to note here is that JPasswordField returns a char[] rather than a string. This is because you have no control over when the String will vanish. While you also have no control over when a char[] will vanish you can fill it with junk when you are done with the password.
I say reduce as this will not stop someone. As long as the password is in memory it can be recovered, and as the decryption has to also be part of the deliverable it too could be cracked leaving your password wide open.

This has nothing to do with Java - the exact same problem (if it really is one) exists for applications written in any language:
If the executable contains a password, no matter how obfuscated or encrypted, everyone who has access to the executable can find out the password.
If an application knows a password or key temporarily (e.g. as part of an network authentication protocol) then anyone who can observe the memory the application is executing in can find out the password.
The latter is usually not considered a problem, since a modern OS does not allow arbitrary applications to observe each other's memory, and privilege escalation attacks typically rely on different vectors of attack.

If the program knows the password, anybody using the program can extract the password.

In theory you could just hook it up to the debugger... set a breakpoint...and read the string contents

Related

Java Securely Handle Password Variable

I'm not the most experienced programmer especially when it comes to desktop applications.
Just an experiment that I am working on is taking a password, hashing it with MD5, then displaying the hash. No problem there.
Now, I know virtually nothing about data structures and how things are stored on the stack. But the aim is for this program to securely handle the password and the MD5 hash so it doesn't leak out into memory and could be potentially recovered.
I've read a number of posts about this, but they all are more concerned with actually storing the password in memory to be retrievable.
Here is the relevant code:
String pass = new String(passwordField.getPassword());
pass = Hashing.md5().hashString(pass, Charsets.UTF_8).toString();
hashField.setText(pass);
And to put it into perspective, link to a screenshot of whats going on:
http://imgur.com/CbNuGtE
As far as I know, I'm retrieving the input from the password field correctly, but I've read storing them as strings is a no-no.
Then I need to display the MD5 sum securely.
Then upon exit, overwrite the data?

Where do we store key/passphrase/salt for encryption?

My app needs to encrypt some data (a user session token). Most examples I see around have a method that generates a Key using a passphrase and a salt, like:
public static Key generateKey(char[] passphrase, byte[] salt) {
...
}
My understanding is that we have three options for generating the passphrase:
Have the user enter it every time the app starts (annoying to the user).
Hard-code the passphrase into the app itself. More convenient for the user, but someone can find out what your passphrase is given your app binary.
Randomly generate a passphrase, but then we have to store the generated Key on disk. Now we've just shifted the problem to having to store the key securely on disk, which also seems impossible. If the attacker finds the generated key, big problem.
Option #1 won't work for me. Options #2 and #3 seem inherently flawed, unless I'm grossly misunderstanding how to go about this (hoping that I am). What's the recommended way to do this if we can't go with #1? Do we put in a bunch of obfuscated hoops for an attacker to jump through and hope for the best?
Thanks
"Do we put in a bunch of obfuscated hoops for an attacker to jump through and hope for the best?" Basically yes. The size and number of the hoops being how hard you want to make it.
If you are not using a server, then whatever you do to obsfucate and encrypt your data is reversible. However, you can make it REALLY hard. For example, a technique I used to protect some video assets.
Replaced the first 1024 bytes of the header (it's MP4) with 1024 bytes taken from the middle of one of the apps image assets. I tried several repairers, all of which failed to automagically recover the file - although it can be done manually. Then...
Encrypted the file using a private key which is 256 bytes taken from another image asset.
When the key is extracted, it's hashed through an algorithm which does all kinds of otherwise non-sensical maths to mangle the key.
Used a pre-compile obsfucator.
I've tried myself to reverse engineer this, even knowing how it's done, and it's so hard as to make the effort not worth the result.
There are numerous discussions on SO which summarise as; If you simply want to stop copying, make it difficult (cost vs reward) but otherwise sleep easy because there is ultimately nothing you can do. If the data is commercially sensitive, then a server coupled with system level security (e.g whole device encryption and no root) is required.
You store the salt along with the encrypted data, it is not secret information. You can derive the key on either something the user enters, or some sort of a device property: (hashed) IMEI, MAC address, etc.
Basically, think who are you protecting your data from and why. Since the user needs this, there is not much point trying to protect it from them. If you store this in a private file, other apps cannot read it on a non-rooted phone. If you want to protect it on rooted phones, encryption might help, but as long as the key resides in the app, or is derived based on something on the device, it is only making it harder, not impossible to recover.
Android does have a system-wide keystore service, but it has no public API and is subject to change. You could use that to protect your key(s), if you are willing to take the risk of your app breaking on future versions. Some details here: http://nelenkov.blogspot.com/2012/05/storing-application-secrets-in-androids.html

Protecting Sections of Source Code [duplicate]

This question already has answers here:
Handling passwords used for auth in source code
(7 answers)
Closed 7 years ago.
I'm writing a Java class that connects to a server and reads messages in a given queue.
I would like to protect the username and password, which, right now, appear as plain text in the source code.
What I'm wondering, is, what is a good way to do this? If I encrypt the username and password in a text file, won't I need to store the key, in plain text, in any source code that accesses this file? And then anyone else who decides to use my class will be able to gain access to these fields.
There is no prompt where someone can enter the key, either, as this class will autonomously be used by the system.
EDIT: this will become a java lib file. But those can easily be decompiled and thus are basically the original class files anyway, right? And the people this is being protected from are fellow developers of other systems who will gain access to this lib file.
My End Goal: is to have the username and password strings not appear as plain text anywhere, and for them to be as difficult as possible to crack.
It is not possible to do this. Even if you encrypt the login/password and store it somewhere (may it be your class or an external file) you'd still need to save the encryption key somewhere in plain text. This is actually just marginally better than saving username/password in plain text, in fact I would avoid doing so as it creates a false sense of security.
So I'd suggest that your class takes username/password as a parameter and that the system which is using your class will have to care about protecting the credentials. It could do so by asking an end user to enter the credentials or store them into an external file which is only readable to the operating system user that your process is running as.
Edit: You might also think about using mechanisms such as OAuth which use tokens instead of passwords. Tokens have a limited life time and are tied to a certain purpose so they pose a good alternative to access credentials. So your end users could get an access token with their,say, Windows credentials, which is then used inside your class to call the protected service.
This is a classic authentication issue, except that here, Eve can wear Bob's skin like a suit. Is that stretching the metaphor? I'm not sure.
The short answer is that there is no true answer, because what you want is something that basically violates information theory, in that anything transmittable is copyable and thus anything accessible can be viewed as no-longer-unique. Even if you had a magic box, they could just yank out the magic box with some serious JVM hacking.
The long answer is that there are a few solutions that are almost pretty okay, by making it really quite darn hard. I suggest you read the article linked, acquaint yourself with the ideas behind SRP, the vulnerabilities the spec entails, and try to figure out how to get the right to use and implement it. The problem is still there though. It's that you want a system that ensures Bob can never become a flesh-chariot, or fall to the dark side.
Fundamentally, you're breaking the tenth law. I agree with Kork, there's no solution that really does what you want, because you're trying to solve a social problem with a technical feat, one that is quite nearly provably impossible.
There are a few ways of handling this problem. The challenge as you've noted is associating an account with this automated process. So, here are some of the possibilities (from least secure to more secure):
Encrypt the username and password with a calculated key.
The calculated key is based on something both the client and the server can infer (like machine name and IP address)
Associate an authentication token with the client (OAuth style).
The token is negotiated by a one time user interaction to set up the client
The negotiated token is used for all future requests
The negotiated token is only valid for that client on that machine using that user account (server uses socket info to determine the match)
Use multiple forms of authentication
OAuth style token
Calculated token based on time + secondary id (requires clients and servers to be synched to the same time server)
It is important to note that your security measures should be more restrictive than it is worth to crack. In short, if all the potential bad guy is only going to be able to get your food preferences of the day you might not need to be as vigilent as protecting something more high profile like a bank account. User names and paswords are not the only means of authentication.
It's not clear which code has to know the user name & password. Are these credentials just for the queue being read? If so, only the server code would need to know them. In that case, you could store them in a server file whose permissions allow only the server code to read them. The file permissions would then be enforced by the server operating system, which presuambly is much better at security than most programmers will ever be.
I know this question is long since abandoned, but I want to point out that of course you can do this by requiring typed credentials at runtime but only storing a hash of the password. Of course, it needs to be a really good hash. Use a standard one, don't make up your own. The whole point of a hash is that even if you plain text the hashed result, no one else will be able to come up with a string that yields that hash, even if they know how the hash is computed.
Of course users can try a brute force attack, and since they know the result they want they can run it fast, so you need to use a highly secure password.

Hide Password Content in Source Code

Does anyone know how to hide the password contents in the source code of a j2me program? i.e. so people cannot see "DBT" as password who read the source code.
public void validateUser(String user, String Password) {
if (user.equals("N0203251") && Password.equals("DBT")) {
switchDisplayable(null, getContinue());
}
}
As other have said. Store the hash, though you still need to use a strong password or an automated guesser will find the one you're using.
But, be warned:
If your attacker has access to the source code he/she/it can alter the stored password hash or just remove the password check.
So this method is of little use unless you can verify the integrity of the code being run, which is hard.
When it comes down to it, you've written a back door into the program. That's a Bad Thing - don't do it.
Like others have said, you can do better by using a hash, but a couple critical things are left out. When someone guesses the password, they'll know the password for every installed copy of your software. Since the password is hard coded, nobody will be able to change it or revoke it, so you'll have inserted a back door in the program that nobody can eliminate. And if you rely on that password ofr any communication with other resources, you can't ever change it - at least, not without significant additional work.
What you should really do is place the password in an external location, such as a hardware security module, or password file, or database table. Then, implement a full password change and rotation mechanism - honestly, this should be pretty much the same mechanism you use across all your passwords.
You could store the hash (MD5 / SHA1) of the password instead and compare this with the hash of the supplied passwords.
Make sure you calculate the hash externally to avoid having the original password mentioned anywhere in the executable.
Use a function that hashes the password - keep the hash of a password in the source, not the password itself.
A quote from that page:
A related application is password
verification. Passwords are usually
not stored in cleartext, for obvious
reasons, but instead in digest form.
To authenticate a user, the password
presented by the user is hashed and
compared with the stored hash. This is
sometimes referred to as one-way
encryption.
If you are storing the application on the user's mobile device, the best you can do is try to obscure the password. I would recommend doing some sort of hashing algorithm (maybe SHA1) or a key derivation algorithm like PBKDF2 and storing the result rather than comparing against the plaintext password.
Storing the hash instead the password buys you absolutely nothing. Since it is now the hash being used to authenticate instead of the password, reading the source code (or reversing the object code) will reveal the hash and allow the attacker to authenticate.
The answer to these questions is always the same. You can't achieve any measurable security if you use hard-coded client-side secrets no matter what you do. The best you can do is obfuscate enough until you get a warm fuzzy feeling that it is good enough.

How to securely store a PrivateKey in code [duplicate]

This question already has answers here:
How do I securely store encryption keys in java? [closed]
(4 answers)
Closed 7 years ago.
I'm working on a software project where the application will end up being run in an untrusted environment. I have a need to perform some ancillary cryptographic signing (meaning this is not the primary means of securing data), but do not wish to leave the key in plain view as such:
private static final String privateKey = "00AABBCC....0123456789";
What method can I use to reasonably secure this? I'm aware that nothing is full proof, but this will add an extra layer in the security wall.
For clarification: I've got what is essentially a String that I don't wish to have easily pulled out in a debugger or via reflection. I'm aware that decompilation of the class file could essentially render this moot, but that's an acceptable risk.
Obviously storing the key offsite would be ideal, but I can't guarantee Internet access.
It's impossible to secure a key in an untrusted environment. You can obfuscate your code, you can create a key from arbitrary variables, whatever. Ultimately, assuming that you use the standard javax.crypto library, you have to call Mac.getInstance(), and sometime later you'll call init() on that instance. Someone who wants your key will get it.
However, I think the solution is that you tie the key to the environment, not the program. A signature is meant to say that the data originated from a known source, and has not been tampered with since that source provided it. Currently, you're trying to say "guarantee that my program produced the data." Instead, change your requirement to "guarantee that a particular user of my program produced the data." The onus is then shifted to that user to take care of his/her key.
Forget about obscuring it in the code. It will only make your software harder to read, debug and maintain. You'll also be nailed if your software has to go through a security audit.
If you can't put the key in secure storage (securely on disk, secure memory or a passphrase in someones head), don't bother with anything else.
If you're in a *nix environment, storing the key on disk with root/root 400 permissions might be "good enough".
On Windows, you could use the DPAPI to store the data in Microsofts secure memory.
You could also use a lightweight PBE to encrypt the sensitive key and have the user enter the passphrase when the application starts up.
Whose private key is that? The private key is supposed to be private, so it is wrong to distribute it.
First off - good on you for thinking about this problem!
Is it possible to instead generate a private key, communicate with your Certificate Authority and have it sign the key (and manage a CRL as well)?
As an alternative, if this is going to be running on Windows, you can use the Crypto API to securely store a private key that is marked as not-exportable. How you distribute that key securely can be another challenge though.
Can you break the private key out into two parts: store one in your program, then interactively request the second half - when your app starts ?

Categories

Resources