Keep password in memory - java

I'm currently working on a project in which I need to keep the user's files encrypted. This part I've achieved easily by using Java's built-in cryptography library. Loading the file from the disk is done by reading the salt from an attached file, having the user input the password, and then generating the salted and hashed key, which is then quickly disposed. But when it comes to saving the files back to the disk, a problem arises because I need to keep the key in memory throughout the whole runtime, or have the user input the password every time I write the file to the disk. What would you recommend in order to keep my application as secure as possible.

To be as secure as possible then your user should enter the password again. However really you need to look at the use-case and decide what you are defending against.
For example if they have to enter the password again then they are more vulnerably to someone shoulder surfing or key loggers, etc but the increased risk is pretty small.
The password kept in memory is only vulnerable to processes already running on the machine the software is running on. That again is a pretty small risk as it would probably be easier just for them to put a key logger on.
So really in this sort of scenario the main risk factors are the people. Can someone trick the person entering the password into revealing it (i.e. spear fishing, fake login prompts, key loggers, shoulder surfing). Mitigating most of those risks is about training, not about technical issues at all.
Far too many people think that a technical silver bullet can solve all their security woes. It really can't, a system is only as secure as its weakest link and you need to think about the big picture as well as the small one.

Related

Is it safe to store Access Token as a String during application's runtime

I am working on an integration, where I need to make repetitive calls to another system.
As of now, I fetch the Access Token for every call, which is extremely bad, as I make more than 300 calls. Fetching token for each call is expensive.
I wanted to get the access token first and store it till the time the sync is not completed, and afterward, I don't want it to be in the memory.
What would the best and secure way to store the token during this time.
I am thinking of using the below dependency to check whether the token has expired or not, if it is expired then only I want to fetch it again.
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>4.0.0</version>
</dependency>
Is this approach correct? If not could someone please tell me what would be the best way to do it?
We (devs) are so not used to think about threat modeling at all. That's why we end up asking questions like these all the time. The proper question is: what are you afraid of?
Are you trying to protect the application from the remote attacker with no access to the client machine? Store the token any way you like and make sure you protect the channel over TLS.
Do you want to protect the app from the attacker that has physical access to the device? Impossible. We sometimes tend to encrypt secrets when they are in memory to protect from dumping memory and analyzing them but this only makes sense with passwords and other static secrets. Tokens usually get rotated to often to have significant amount of time to perform such attack.
The problem arises, when you want to store the secrets physically on the drive somewhere to be available for many user sessions. In this case encryption might be the answer. But guess what? Once you encrypt now you have the problem with protecting the encryption key! So you did not solve the problem, you just shifted it somewhere else.
You can also play the game otherwise. Go and ask the security department (assuming you work for a company) which security requirements are to be fulfilled when dealing with secrets like tokens.

Prevent application from being copied/generate activation password

I made a Java (on IntelliJ IDEA) application and I want to give it to someone via USB or Dropbox.
However I don't want him to give it to someone else, like you know, he downloaded the file, so he can copy/paste it to his USB and give it to more people.
Is there any way to prevent the application from being copied after I give him the application? At first I thought of making a login window, but then I thought "hey, if he knows the password to login to application, he can just give the application to someone and give him the password as well", so login window is not an option (I think?). Can I disable the copy/cut functions with If statements after being copied once?
Or I can only prevent it by linking my application with a database and generating unique passwords to activate my application? Like for example, someone requested to use my application, so I will give him the application but he won't be able to run it. Then I generate a password and sent him the password. However that password can only be used once so if he will try to use the same password on 2 different PCs, it will give him an error. Is there any guide/tutorial/tips of making something like that on Java?
You could create some kind of "activation code" for your software that is generated based on some information about the hardware it's running on. I've seen some people using, for example, the MAC address, that you can obtain in a platform-independent way in Java.
However, keep in mind that those techniques will only work against the most basic users. MAC addresses can be easily changed by anyone that knows how to use Google and even if you use something incredibly complicated instead of MAC addresses, Java programs are dead simple to decompile and once the attacker knows what function is checking if the program is correctly activated, he/she can easily replace it. Yes, you can obfuscate your bytecode, but it only makes the task a little harder, not impossible.
You can do what you suggested and use passwords that can only be used once, but then your program needs to know that it has been activated, by storing that information somewhere (a file or something like that). And once the user knows where that information is stored, it can be replicated on other computers.
Unfortunately, once the user has your program, you have no control over what he/she can do. You can make sure that the user is not going to do stuff he/she is not supposed to do with your program by not giving him/her the program at all. You can, for example, expose your program's features through the web. But, as you said, nothing stops an user from sharing login credentials with another person. Yes, you could check if the user is accessing the page from a different IP address, but then a legitimate user could have problems when, for example, accessing your program from a different wifi network. And in this case, your protection not only fails in solving the problem, but also becomes annoying to a honest user.
In summary, brilliant engineers at huge software companies have been working on protections for their software for years and I'm yet to see a software that cannot be illegally activated given enough time and effort.

Access Files On Shared Drives Without Mapping

I have written a program that can go out and check file version info for a particular file. This needs to happen on a large scale basis, something like 8000 computers or so. The way I've been doing it up until now is mapping the shared path I need to a drive letter, checking the required file, and then unmapping the drive. Each one of these shared areas requires the same username and password to be entered for security purposes. As you would imagine, mapping and unmapping the drive in order to check file version info slows my program down. So, I was wondering, is there any special way that is more efficient, and quicker to do this?
Keep in mind, this does have to go across a network, so I don't think it will ever be lightning fast but if someone could provide some design pointers for a better solution I would be all ears.
Thanks and I appreciate it! Or if anyone has heard of libraries which simply this process that would be great if you could share them. At the moment this is written in C#, soon to be re-written in Java.

Java Encrypting logs

I am currently making a game. I have build logging facilities internally, and there are message types like general, log, exception, send, receive, debug.
The send and receive logs contain the raw logging information, so they really contain what I send over the network.
The game uses a client-server model and uses a SSL connection such that the network information cannot be altered. However for the logging I would be logging the text as plain text, and that obviously will cause trouble. Also I plan on simply masking (by *'s) any personal information (like passwords, etc.)
However I have a few concerns:
The client program contains the truststore to use with SSL and the server's hostname/IP and port are not really a secret either. So if a person knows what to send over the network, then he can act like he is the client, right?
If a person can see what the client sends and receives, then he might be able to make a bot very easily. (The game is a turn based 2D game, so by simply relying on all network data you should be able to play the game I think. There is no skill with the mouse required in any way.)
So all in all: How can I still log all information and write it to a file, but without anyone else being able to read, modify it or use it in any way?
All comments are greatly appreciated, and I would also appreciate concrete suggestions as how to implement such a system.
Regards.
If you're worried about encrypting data on your server, then the easiest solution is a whole-partition encryption program like Truecrypt - this will protect the server data if somebody steals the machine / hard drive.
If you're encrypting data on the client's machine, then this means that the encryption key must also be somewhere on the client's machine (even if it's in main memory). Go ahead and encrypt or obfuscate the log information to make it more difficult for users to read it, but be aware that a user will still be able to read it if (s)he puts enough effort into it. That said, the best way to obfuscate the data is to encrypt it with a key that is never saved to disk - for example, when a user logs in then send them a fresh encryption key that their client app will use to encrypt log data; on your server, keep a record of what keys you've sent to the client and at what UTC timestamp. Store the logs with an unencrypted timestamp, so that when the user's client app sends log data you'll know which key to use to decrypt it. Obviously the user can easily change the timestamp, but this is equivalent to the user simply deleting the log data from their machine (which you can't prevent); meanwhile it is fairly difficult for the user to figure out what key was used to encrypt the data, so it's not easy for the user to read or forge log data (but again, the user CAN read / forge log data if they put enough effort into it).
You can take steps to obfuscate the encryption key in memory by e.g. storing it in multiple pieces. For example, assuming you're using AES 128, you can store the key in two 64-bit chunks that you concatenate before encrypting data, then wiping the concatenated key from memory as soon as you're done with it. Or you can store two 128-bit keys that are Xor'd together, again wiping the Xor'd key from memory as soon as you're done with it. A dedicated user can still figure out the key, but this will make it a bit more difficult for them.
Another step you can take is to use an encryption algorithm besides AES, e.g. any of the other AES finalists like Twofish or Serpent (don't implement your own encryption algorithm, you're better off broadcasting that you're using a strong algorithm like AES than you are using a weak obfuscated algorithm). Just remember to obfuscate the encryption library's class and method names to make it more difficult for the user to figure out what encryption algorithm you're using. (This is much more effective if you're compiling to machine code - it's probably not worth it if you're using Java, because the user can simply decompile your code and use your own decryption code to decrypt the log files.)
In terms of figuring out if a player is a human or a bot, not even games with much greater budgets than yours are able to reliably do this - all you can really do is boot the user or send them some sort of captcha if they exhibit "bot-like" behavior, but this isn't fool-proof, and you really ought to favor not annoying legitimate users over booting bots.
There's not much you can do. If the client is written in Java it is pretty easy to reverse engineer, or to use something like AspectJ to monitor what the client is writing to the network. Likewise for any data that is written to a logging system, even if it is ultimately encrypted.
I have the exact same need as you. Some guy called 'maybeWeCouldStealAVa' has written a great implementation in: How to append to AES encrypted file
I've confirmed that it works, however when I 'flush()' at the end of each line, I'm missing the last part of the message - up to 16 bytes - until the next message is written. I could close() at the end of each line, because this seems to be the only way to write the padding. But at least it doesn't need to read the whole file in order to be able to append to it.

Stopping the manipulation of variables used for data collection?

I am working on a project in java and I was hoping to be able to collect statistics from the client and a possible problem that I fear will occur is the manipulation of the variables used for collection which will lead to illegitimate statistics. Is it in any way possible to prevent the manipulation of variables or is it always possible?
For example: I want to log the actions made per hour from the client. The variable acting as a counter for the amount of actions performed is manipulated and a much larger amount is added to the counter. This data is then uploaded to the server (Of course using a multi-tier architecture to prevent even more possible problems) and considered 'legit.'
Is there any way to prevent this?
Depending on how the data is uploaded, there are various ways to secure the information.
If you are uploading some kind of text or data file, using basic encryption, even a ZIP with a password, should be sufficient to stop casual users from changing the information.
Your application could also simply use RMI or a web service to upload the information, never giving the user the change to manipulate the data.
All of this of course assumes that the application itself gathers the information - if users have the opportunity to enter the data, there's no real way of preventing them from giving you bogus information.
Without knowing if this is a desktop or web application, I'm going to suggest you encrypt your upload files somehow. It doesn't have to be complicated, just enough so someone can't edit it in a text editor.
Just remember that if something runs on the client machine, it can be manipulated. Java is not a secure language, nothing is, for that matter, and while you can do many things to secure applications, there's always someone just a little smarter out there that can crack it.
If I was doing this, I'd do the accumulation of the statistics on a secured machine. Have the primary data gathering code send "event" message to the accumulator, and have the accumulator keep a log of the raw events and their arrival timestamps. This won't prevent people manipulating the stats, but it could make it easier to detect suspicious patterns after the fact.
Building on that idea, you could arrange that event generator application (on the user's computer) uses some kind of handshaking involving a shared secret or public/private key encryption. I don't think you can fully secure this, but security-by-obscurity could be enough to deal with attempts to cheat by people without the skills to reverse engineer the code.
But like Ewald says, any algorithmic process can be reverse engineered by someone who has sufficient control of the hardware it runs on. If the process needs to use a "secret" to operate, then that secret can be revealed.

Categories