Background
We generally encounter the scenario where we need to hold very sensitive information such as passwords, credit card numbers or personal data in some variable and move it across the application for further use and action. We generally use the System.String Data Type class to hold such information. Is it safe?
Limitations of System.String
String variables are created in the heap and are cleaned up by the Garbage Collector to reclaim the memory as needed. In many cases, this value may not be cleaned up for as long as 2 hours on the servers. So, there is a risk of the information being revealed after use because your application cannot delete the data from computer memory.
Solution
.Net 2.0 and onwards provides a secure way of managing such sensitive data. It provides the SecureString class that inherits from System.Object. SecureString data is stored in RAM so the Garbage Collector doesn't move it around or make copies of it.
This class resides in the System.Security namespace. This class, by default, implements the IDisposable interface. Once you are finished using this class variable call the Dispose method in a try / catch block. Another better way of disposing of them is to use it within a using statement.
A SecureString object is similar to a String object in that it has a text value. However, the value of a SecureString object is encrypted and can be deleted from computer memory by either your application or the .NET Framework garbage collector. Even if the user takes a memory dump with malicious intent, the contents of this variable will not be available.
To save this instance from accidental or malicious exposure, none of the member methods or properties of this class allow the value to be converted or compared. However, that said, using some members of the System.Runtime.InteropServices.Marshal class, it is possible to manipulate the value of this instance.
- public class Example
- {
- public static void Main()
- {
-
- SecureString password = new SecureString ();
- ConsoleKeyInfo consoleKey;
-
- Console. Write ("Enter password: ");
- do {
- consoleKey = Console.ReadKey (true);
-
-
- if (((int) consoleKey.Key) >= 65 && ((int) consoleKey.Key <= 90)) {
-
- password.AppendChar (consoleKey.KeyChar);
- Console. Write ("*");
- }
-
- } while (consoleKey.Key! = ConsoleKey.Enter);
- Console.WriteLine ();
-
- try
- {
- Process. Start ("Notepad.exe", <USERNAME>, password, <DOMAINNMAE>);
- }
- catch (Win32Exception e)
- {
- Console.WriteLine (e.Message);
- }
- }
- }