I am retrieving an unencrypted
key from a MemoryStream
, converting it to some kind of string, and using that string with .Net's crypto
functions to encrypt data. I need to make sure the unencrypted
key is wiped from memory after using it. I found SecureString
, which I think will take care of the string, but I'm not sure how to wipe the memory of the key before it becomes a SecureString
.
So the way everything works is:
MemoryStream -> char[] -> SecureString
SecureString
is passed the pointer to the char array, so it wipes the char array when it is finished? This is it's constructor:
SecureString(Char*,int32)
There is an example implementing it here.
However, once the SecureString
wipes the data (if it wipes the data), I still need to know how to wipe the data in the MemoryStream
, and any intermediate objects I have to create in order to get the char[]
.
So this question boils down to two parts:
How does one read a MemoryStream
straight into a char[]
without producing anything else in memory? (And if that isn't possible, what is the ideal transition? ie, MemoryStream -> string -> char[]
?)
and,
How does one overwrite the memory used by the MemoryStream
(and any other signatures created in the MemStream->char[]
process) when finished?
You can re-use the MemoryStream by Setting the Position to 0 and the Length to 0. By setting the length to 0 you do not clear the existing buffer, it only resets the internal counters.
Overall, SecureString is more secure than String because it limits the exposure of sensitive string data. However, those strings may still be exposed to any process or operation that has access to raw memory, such as a malicious process running on the host computer, a process dump, or a user-viewable swap file.
A SecureString object is similar to a String 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 .
From expirience I can say, that it does not copy the array. Be aware though, that you are unable to resize the memory stream, when using an array in the constructor.
First of all, SecureString
doesn't wipe the memory of the input char*
- you're responsible for that. It will only clean up its own internal storage.
To read/clean the contents of the MemoryStream
into a local char[]
, you can simply allocate the array (assuming that your stream contains a valid string):
// Get the contents of the stream.
var byKey = oMS.GetBuffer ();
fixed ( byte *pBytes = byKey )
{
var oSecStr = new SecureString ( (char*) pBytes,
(int) ( oMS.Length / 2 ) );
// Clear stream (there's no separate char/byte array
// to clean).
Array.Clear ( byKey, 0, byKey.Length );
}
This all, of course, assumes unsafe
code. There's, however, no fully guaranteed way to clear all potential instances of the key from memory - during the calls to get the key into the stream, it may be copied a number of times (in various private buffers you have no access to) so you probably won't even know the number of copies lingering around.
What you are trying is more problematic than you might think. A MemoryStream is most likely used by something else and most likely grows in size over time.
Every time it grows, the data is copied into a new array internally and the old one is freed => your key could leak here
Also, a MemoryStream is most likely used by some other API. The other APIs will most likely not securely delete the key, because they are not designed to do so.
But to answer your original question: If the key is just ascii characters, you can just copy the bytes into a char array and overwrite the original bytes with random junk. You can acces its contents directly using GetBuffer
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With