I have a c# byte[] containing sensitive data. What is the best way to clear it? How do I ensure that something like Array.Clear will not be optimized away?
I cannot think of any circumstance in which a call to Array.Clear
would ever be optimized away and even if it could it would only be optimized away in instances where your byte[]
was cleared already.
Edit: Something else to consider would be finding out if the framework's SecureString
implementation would be useful in your situation:
A
SecureString
object is similar to aString
object in that it has a text value. However, the value of a SecureString object is automatically encrypted, can be modified until your application marks it as read-only, and can be deleted from computer memory by either your application or the .NET Framework garbage collector
If you're concerned about Array.Clear, you could always just Marshal.Copy an empty byte array onto the sensitive data.
For example, like this (assuming 'data' is the byte[] containing the sensitive information):
byte[] clear = new byte[data.Length];
unsafe
{
fixed (byte* ptr = &data[0])
{
Marshal.Copy(clear, 0, new IntPtr(ptr), data.Length);
}
}
I was under the impression that there were already techniques to show the recent state of RAM. Then there's also the MIT guys that flash froze some RAM, lifted it and took it somewhere else and maintained all of the state.
So, if you were paranoid, you'd randomly write a whole bunch of data over your array a few times.
AFAIK there is no equivalent to SecureZeroMemory in CLR. You should use SecureString to store your data.
Even if Array.Clear is guarenteed to be executed (not optimized away) I think you still may have a problem. The GC can move objects around in the heap and there is no guarentee that traces of the original byte will linger if it was moved from one location to another before Array.Clear was called.
You may want to check out SecureString, ProtectedData, or ProtectedMemory. But, if you want a more manual approach I think you are going to have to at least pin the byte array so that the GC cannot move it around. I believe the SecureString uses this trick as well.
A trick that works with most C compilers is to do something like sum all the elements of the cleared array, and then do something with that sum, like print it or xor it with your return value. That way the dead code elimination won't eliminate the clearing of the array.
That said, are you sure that you only need to clear this array? Consider all the other places where the value may also have existed: a buffer in a form, string objects being passed around, key equivalent values in intermediate calculations, or paged out to disk. Zeroizing this one array only gets you 1% of the way there. You have to clear the entire key path.
If you're writing your own encryption routine, my advice would be: don't. You'll get it wrong (as would I, as would anyone who's not a security expert). Use a well-known, tested library.
(If not, never mind!) :)