Last Updated: February 08, 2018
·
2.43K
· artfulhacker

.net SecureString but what about other data types?

I have used secure string before but now I needed to protect other types of objects in memory, what is the best way to do this?

Start with the following example, taken from here:

using System;
using System.Security.Cryptography;

public class DataProtectionSample
{
// Create byte array for additional entropy when using Protect method. 
    static byte [] s_aditionalEntropy = { 9, 8, 7, 6, 5 };

public static void Main()
{
// Create a simple byte array containing data to be encrypted. 

byte [] secret = { 0, 1, 2, 3, 4, 1, 2, 3, 4 };

//Encrypt the data. 
    byte [] encryptedSecret = Protect( secret );
    Console.WriteLine("The encrypted byte array is:");
    PrintValues(encryptedSecret);

// Decrypt the data and store in a byte array. 
    byte [] originalData = Unprotect( encryptedSecret );
    Console.WriteLine("{0}The original data is:", Environment.NewLine);
    PrintValues(originalData);

}

public static byte [] Protect( byte [] data )
{
    try
    {
        // Encrypt the data using DataProtectionScope.CurrentUser. The result can be decrypted 
        //  only by the same current user. 
        return ProtectedData.Protect( data, s_aditionalEntropy, DataProtectionScope.CurrentUser );
    } 
    catch (CryptographicException e)
    {
        Console.WriteLine("Data was not encrypted. An error occurred.");
        Console.WriteLine(e.ToString());
        return null;
    }
}

public static byte [] Unprotect( byte [] data )
{
    try
    {
        //Decrypt the data using DataProtectionScope.CurrentUser. 
        return ProtectedData.Unprotect( data, s_aditionalEntropy, DataProtectionScope.CurrentUser );
    } 
    catch (CryptographicException e)
    {
        Console.WriteLine("Data was not decrypted. An error occurred.");
        Console.WriteLine(e.ToString());
        return null;
    }
}

public static void PrintValues( Byte[] myArr )  
{
      foreach ( Byte i in myArr )  
        {
             Console.Write( "\t{0}", i );
         }
  Console.WriteLine();
 }

}

Use these methods in this example to protect objects held in memory, all .net objects can be represented with a byte array some with native methods to serialize and deserialize them. You could then use public get and set methods to retrieve and store the data.

The following shows how we can store a guid in a class using protected data:

public Guid secureGUID
{
    get
    {
        return new Guid(Unprotect(_secureGUID));
    }
    set
    {
        _secureGUID = Protect(value.ToByteArray());
    }
}

private byte[] _secureGUID;

The other thing you will want to make sure you do is run the Array.Clear on dispose of the class, to ensure the array data has been overwritten with zeros in memory.

1 Response
Add your response

Hi Mike, thank you for the post it's very helpful. I have a question and hope you can reply. When I checked the dumped memory, the Guid property in the class is encrypted. But the Guid value can still be found from a "Guid" type from memory. I think that's because of the "get" method of Guid property. Am I correct? So that means if the Guid value is sensitive, we can still find it from memory, how to solve it?

Hope can get your response, thank you in advance.

-Eric

over 1 year ago ·