[System].String objects contains an array of characters that reside somewhere in memory. We usually store our confidential entities (information that is meant to be secure) in these String objects. This information can range from your password to you salary code. If some un-managed/ unsafe code is allowed to run, that code can get into our process's address space, find out the required String object and use it in any way as it like.
As we all know, Strings objects are immutable i.e. once a string object is created they never change. Old versions of String object are scattered all over memory. There is no guarantee when garbage collector will run and clean up our application’s managed heap. Before GC wakes up, these string objects are within reach of some unsafe code. Unsafe here means code that is manipulating memory pointer. Even if string objects are used for short time and then are garbage collected by the run time, this doesn't mean that memory space used by string will be allocated to another object just after garbage collection (especially if string object was in older generation).
If some government office like CBI (Indian Investigating Agency) approaches you to create a secure application which will handle data about national security, “System.String” type objects will not meet stringent security requirements that application needs. Sensitive information lying in memory can be very tempting for anti social elements (this includes hackers). Due to these requirements Microsoft introduced another type of string class:
- Class Name: SecureString
- Name Space: System.Security
When we create an object of SecureString type, it internally allocates a block of memory that contains an array of characters. Now the surprise! this is an un-managed block of memory and this is because runtime don't want garbage collector to know about these SecureString objects. GC knows about all the objects lying in the heap. It has no information regarding object type but it knows its memory address. This class is just in its budding phase and does not provide only few features that are provided with System.String class. Data is encrypted before storing and decrypted before being read. So with good functionality it gives us some bad performance overheads.
System.Secure.SecureString class implements Dispose pattern i.e. it implements IDisposable interface. Another surprise, its Dispose method is called implicitly (i.e. automatically). You don’t need to call this method explicitly. CLR calls SecureString’s Dispose when it realizes that this string is not needed or it is out of scope. Dispose ensures that all memory contents used by object of SecureString type are zeroed out. This class is derived from CriticalFinalizerObject which ensures that finalize method of this class is called no matter what happens. CriticalFinalizerObject in itself deserves a good amount of space. But I’ll leave it for now.
There are certain limitations around usage of SecureString in .Net 2.0.
to be continued…