Introduction
SecureString represents text that should be kept confidential. The text is encrypted for privacy when being used, and deleted from computer memory when no longer needed. This class cannot be inherited.
Background
We all are aware that the System.String
class is immutable. Once after using it if we don't need it anymore, it cannot be programmatically scheduled for garbage collection; that is, the instance is read-only after it is created and it is not possible to predict when the instance will be deleted from the memory.
As a result, it is risky to store sensitive information such as a password, credit card number, or personal data within a string object. There is a risk of information being revealed after it is used because your application cannot delete data from computer memory.
To come over such a scenario, MS has introduced an additional object SecureString
which is very similar to a String object and stores 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.
The value of an instance of SecureString
is automatically encrypted when the instance is initialized or when the value is modified. Your application can render the instance immutable and prevent further modification by invoking the MakeReadOnly method.
Using the code
The example below demonstrates how to use SecureString
to secure a user's password for use as a credential to start a new process.
Let's create a sample console application, and add a class Misc
.
I will be writing a simple method to assign a string text to the secure string and check whether the data remains confidential.
public class Misc
{
SecureString securePwd = new SecureString();
public SecureString convertToSecureString(string strPassword)
{
var secureStr = new SecureString();
if (strPassword.Length > 0)
{
foreach (var c in strPassword.ToCharArray()) secureStr.AppendChar(c);
}
return secureStr;
}
In the above code, we are taking a string parameter and copying it to
SecureString
and sending the SecureString
object.
Now, we will go ahead and call this method from our
program.cs file.
class Program
{
static void Main(string[] args)
{
SecureString sec_strPassword = new SecureString();
string strPassword = "ZAQ!2wsx";
Console.WriteLine("Secure String Example..");
Console.WriteLine("Password : " + strPassword.ToString());
if (strPassword.Length > 0)
{
Misc miscObj = new Misc();
SecureString secureString = new SecureString();
sec_strPassword = miscObj.convertToSecureString(strPassword);
strPassword = "";
Console.WriteLine("Password converted to Secure Password : " + sec_strPassword.ToString());
Console.WriteLine("Cleared actual Password : " + strPassword.ToString());
}
}
}
Rebuild the application, and execute it. You will see the below output:
Secure String Example
Password : ZAQ!2wsx
Password converted to Secure Password : System.Security.SecureString()
Cleared actual Password :
The password information string which we copied to the SecureString
object is not exposing the text within it. Instead, it returns the object type. By this, we are sure that our sensitive information is hidden now.
I am going to write another method to retrieve the encrypted
SecureString
information back to the string variable. Edit the Misc.cs file and add the below code:
public string convertToUNSecureString(SecureString secstrPassword)
{
IntPtr unmanagedString = IntPtr.Zero;
try
{
unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(secstrPassword);
return Marshal.PtrToStringUni(unmanagedString);
}
finally
{
Marshal.ZeroFreeGlobalAllocUnicode(unmanagedString);
}
}
We will be calling this method from our program.cs file:
static void Main(string[] args)
{
SecureString sec_strPassword = new SecureString();
string strPassword = "ZAQ!2wsx";
Console.WriteLine("Secure String Example..");
Console.WriteLine("Password : " + strPassword.ToString());
if (strPassword.Length > 0)
{
Misc miscObj = new Misc();
SecureString secureString = new SecureString();
sec_strPassword = miscObj.convertToSecureString(strPassword);
strPassword = "";
Console.WriteLine("Password converted to Secure Password : " + sec_strPassword.ToString());
Console.WriteLine("Cleared actual Password : " + strPassword.ToString());
strPassword = miscObj.convertToUNSecureString(sec_strPassword);
Console.WriteLine("Copied Un Secured password from Secure Password : " + strPassword.ToString());
Console.ReadKey(true);
}
}
Rebuild the application, and Execute it. You will now see the below output.
Secure String Example
Password : ZAQ!2wsx
Password converted to Secure Password : System.Security.SecureString()
Cleared actual Password :
Copied Un Secured password from Secure String : ZAQ!2wsx
Here, we are able to retrieve our sensitive information from the SecureString
object.
Finally, let's do another quick check with the SecureString
object.
We will be modifying our Main code to start a new process by passing Domain, User, Password, and Process Name. The process will be triggered if the information passed is successfully authenticated. I will add this code in our Main program:
try
{
Process.Start("Notepad.exe", "Harry.s", sec_strPassword, "MYDOMAIN");
}
catch (Win32Exception e)
{
Console.WriteLine(e.Message);
}
Let's do a final run to see what this will do. You will notice a new Notepad window appear once the process authenticates the information passed.
Around 9 Years of IT development experience across various domains like ERP, LMS, Sales, Accounting, Shopping Carts, Web Development, Mobile Web Development and Client Server Applications using Latest MS Technologies like MVC4, WCF, ASP.NET 2-4, C#, Crystal Report, SQL Server and MSBI Tools.
I am working as a Technical Lead/Project Manager in one of the leading Hyderabad based IT Company.