We mostly think about security while transporting data from a client machine to server and authentication/authorization at the server end. What about the memory? We save confidential info like user’s password and other key secrets into a variable for processing, variable’s value saves in memory. Unfortunately, string is immutable means every time you reassign a value to it, a new instance in memory will be created and the old instance location don’t wipe out. So, there can be multiple locations of passwords saved into memory.
Suppose if in case someone has access to that server memory for websites. No doubt WPF/Win Forms apps’ memory is not always secured. A user can use WPF/Win Forms app on public computers as well. We need a way to secure our data that we save into variables also. One possible solution is to use SecureString, an alternative to String.
SecureString is mutable, saves info in memory in encrypted form. We can dispose the instance of it as soon as we are done with our variable. No need to install any special package for using this. It uses the underlying operating system’s encryption.
- We can also convert SecureString value to string. This can be done using Marshal class:
SecureStringToBSTR: Converts the value to a binary string (BSTR).
- SecureStringToCoTaskMemAnsi and Marshal.SecureStringToGlobalAllocAnsi: Copies the value to an ANSI string in unmanaged memory.
- SecureStringToCoTaskMemUnicode and Marshal.SecureStringToCoTaskMemUnicode: Copies the value to a Unicode string in unmanaged memory.
Again we are back to a String class where the problem arises. Don’t worry each of the above methods also provide a way to clear out the string data from memory. You can see below the corresponding method for each conversion type:
- Marshal.ZeroFreeBSTR for Marshal.SecureStringToBSTR.
- Marshal.ZeroFreeCoTaskMemAnsi for Marshal.SecureStringToCoTaskMemAnsi.
- Marshal.ZeroFreeCoTaskMemUnicode for Marshal.SecureStringToCoTaskMemUnicode.
- Marshal.ZeroFreeGlobalAllocAnsi for Marshal.SecureStringToGlobalAllocAnsi.
- Marshal.ZeroFreeGlobalAllocUnicode for Marshal.SecureStringToCoTaskMemUnicode
SecureString secureStr = new SecureString();
if (creditCardNo.Length > 0)
foreach (var c in creditCardNo.ToCharArray())