Click here to Skip to main content
Click here to Skip to main content

Working with SecureString

, 19 Nov 2013 CPOL
Rate this:
Please Sign up or sign in to vote.
Handling confidential information using SecureString class.

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
{
    // Instantiate the secure string.
    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();

            //Converting UnSecure String to Secure String
            sec_strPassword = miscObj.convertToSecureString(strPassword);

            //Clearing strPassword Text
            strPassword = "";

            //Confirm Converstion, and Trying to retrieve Secure String Information 
            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();

        //Converting UnSecure String to Secure String
        sec_strPassword = miscObj.convertToSecureString(strPassword);

        //Clearing strPassword Text
        strPassword = "";

        //Confirm Converstion, and Trying to retrieve Secure String Information 
        Console.WriteLine("Password converted to Secure Password : " + sec_strPassword.ToString());
        Console.WriteLine("Cleared actual Password : " + strPassword.ToString());

        //Converting Secure String to UnSecure String.
        strPassword = miscObj.convertToUNSecureString(sec_strPassword);
        
        //Confirm Converstion: You can see the String output
        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
{
    //Passing Secure string to Initiate New Process, This line below will start a new 
    //Notepad Instance if the User and Password authenticates correctly.
    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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Harry Panesar
Program Manager
India India
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.

Comments and Discussions

 
GeneralMy vote of 1 Pinprofessionalzomorrod.company6-May-14 6:56 
GeneralWish this was an implicit converter [modified] Pinmemberbbranded1-Oct-13 9:05 
QuestionMy vote of 3 Pinmemberpoji19-Feb-13 21:51 
AnswerRe: My vote of 3 [modified] PinmemberHarry Panesar20-Feb-13 2:52 
GeneralRe: My vote of 3 PinmemberOleg A.Lukin19-Nov-13 19:45 
GeneralMy vote of 4 PinmemberKlaus Luedenscheidt19-Feb-13 20:51 
GeneralRe: My vote of 4 [modified] PinmemberHarry Panesar20-Feb-13 1:30 
GeneralRe: My vote of 4 PinmemberKlaus Luedenscheidt22-Feb-13 18:30 
GeneralRe: My vote of 4 PinmemberHarry Panesar23-Feb-13 2:37 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.141216.1 | Last Updated 19 Nov 2013
Article Copyright 2013 by Harry Panesar
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid