Reputation: 1805
I have a code and i wonder can JIT be prevented from optimising method clearArraySafely? Is it possible to selectively disabling the JIT for some part of code?
Or how can I be sure that this code will not be optimized?
private static char[] password;
public static void clearArraySafely() {
// Overwritting array
for (int i = 0 ; i <= password.length; i++) {
password[i] = 0;
//System.out.print(i); // <- I don't want to do this trick to be sure
}
password = null;
}
Is there any good class to store password insted of char array?
Upvotes: 1
Views: 1474
Reputation: 1083
The compiler can't optimize those assignments away because it doesn't know if there are other references to that array. The variable password
is a reference to an array, not the actual array. Consider this:
char[] passwordCopy = password;
clearArraySafely();
// do something with passwordCopy
This code will break if the compiler removes the zeroing. If Java used reference counting then I suppose it could "optimize" it if it sees a refcount of 1, but that hardly seems like something worth doing. Most of the time people aren't writing code to change things that subsequently get discarded.
You might also want to consider using GuardedString
.
Upvotes: 0
Reputation: 718718
There are two answers to this Question:
AFAIK, there is no way of "turning off" optimization for a method without turning it off for everything.
You can do things that are likely to inhibit the particular optimization you are worried about for current generation Java compilers. For instance:
private static char[] password;
public static String dummy;
public static void clearArraySafely() {
// Overwritting array
for (int i = 0 ; i <= password.length; i++) {
password[i] = 0;
}
dummy = new String(password);
password = null;
}
The JIT compiler cannot optimize away the zero assignments. If it did, then the dummy String would be created with the "wrong" contents. And since dummy
can be accessed by reflection without breaking any JLS rules, the JIT can't apply escape analysis to avoid creating it.
Note however, that there is always the possibility of some future generation JIT compiler being ... cleverer. If you want to avoid that, you'd need to make sure that dummy
affects the program's output in some way; e.g. by printing it.
Is there any good class to store password insted of char array?
AFAIK, none that won't suffer from the same problems.
Having said that, going to this level to protect a password is (IMO) bordering on paranoia. If someone has the level of access required to steal a password out of unreachable objects in the heap, they can most likely get the password other ways; e.g. by intercepting the characters at the OS level, or by "debugging" your JVM.
My paranoia is associated with the debug JVM.
Well unfortunately, your paranoia won't help.
For instance, the schemes you designed to prevent someone attaching a debugger can be defeated by reverse engineering and then modifying the exe
file. And so can any other schemes you devised.
If a user controls the platform on which your program is executed, it is not possible stop him/her from "debugging" the running program. The only way to prevent it is to only run the application on a platform that you control.
(BTW - this is not a Java specific problem. It applies to all programming languages. Some are easier to "hack" than others, but they can all be hacked if the unscrupulous user is skilled and motivated, and has the time to develop the "hack".)
Upvotes: 3