I am writing an application that lets the user input sensitive information. When the user clicks "Save," I would like to be able to take that information and encrypt it for storage in a MySQL database. However, I am wary of using a String to store that information, even temporarily, because a memory dump would be able to find that String even if I reassign the variable to null. I also have the issue of what to do when I decrypt the information to display on the screen. Ideally, I will treat the data as the encrypted array of bytes until the last possible moment of displaying it, and holding that information in a secured place in memory.
I see that in .NET there is a SecureString for such tasks, but I can't find an equivalent in Java. Anyone have an idea?
One thought I've had is to use a StringBuffer and to zero it out after using it. Would that nuke the memory space that held the sensitive data?
All security designs start with questions:
1) what are you trying to secure?
2) what threat model are you protecting from?
I don't understand your posted concern. If the bad guy is snooping on your running VM/JVM, you have lost. Nothing you can do will keep the bad guy away from your data if they are already in the JVM. Its too late.
Its not clear that enciphering data and storing it in the MySql (or any other DBMS) actually adds any real security. I have implemented it when the PHB insisted, but it rarely adds anything, let alone enough to justify the engineering and operational hassles that it causes.
What are you really trying to do?
What are you worried about?
Joined: Mar 31, 2011
I'm a newb so forgive the lack of clarity. I don't have a particular threat model in mind, as I'm just learning how to think about these issues. This code is a learning project, not intended for production.
The reason for encrypting the data in the database is to protect the data at rest. Encrypting that data (assuming the keys are managed properly) means that, in the (inevitable) case of a data breach, PCI/HIPAA/etc. would not require notifying those whose data has been compromised. Some effort up-front can prevent a huge expense down the line. I'm sure Sony would attest to that.
Your point that, if an attacker has access to memory, the data is already lost, is well taken. I had come to that conclusion because JTextComponents return their text as unprotected Strings. The plaintext is already there. I'm not trying to rewrite Swing.
There are ways of authorizing access to segments of memory, aren't there? Perhaps an object could be created within protected memory, accept input, and encipher it before it has the opportunity to leave the memory? Or would the entire JVM be within protected memory if any of it is? I don't really know how that works.
There is very rarely any reason to encrypt it in the database. Consider for a moment, how does your code access the encrypted data? Consider how a BadGuy(tm) would try to access your data, and how that differs from how your official application accesses it.
For your production code, you have to supply a password to unlock the DBMS' crypto. Where do you keep that password? As we have noted above, when its in memory, if you are worried about a BadGuy in memory, you are already dead. How does your application get the password? Ask an operator? What happens when the computer crashes and/or reboots in the middle of the night? Who is going to come into the datacenter and enter it? Read it from a file? How do you keep the BadGuy from reading the same file?
Short of highly specialized key storage hardware, you can't. Period.
As to your question about protecting segments of memory, some operating systems can do that in some cases. This is not something that a JVM can do, nor anything that a Java programmer can do. Any college Computer Science textbook on operating systems will explain how its done. Of course, the world's most popular operating system rarely bothers to try to protect memory from anything.