gogole
gogole

Reputation: 151

Considerations in building a Secure string type

I have begun building a secure string type - which i call SecureStringV2 - to extend the existing SecureString type in the .Net framework. This new type is going to add some basic functionality (checking for equality, comparing etc) to the existing type but still maintain the security provided by the SecureString type, that is clear everything out of memory after the types' use. I plan to achieve these features using the Marshal class and hash algorithms. Pointers on how to get this done and done right would be appreciated. Does any of you see any problems with my ideas of implementing this? Thank you :)

Update: This is where my ideas have lead me so far with respect to the core class of the library. take a look and let me know your thoughts.

/// <summary>
///  This class is extension of the SecureString Class in the .Net framework. 
///  It provides checks for equality of multiple SStringV2 instances and maintains
///  the security provided by the SecureString Class
/// </summary>
public class SStringV2 : IEquatable<SStringV2> , IDisposable
{
    private SecureString secureString = new SecureString();
    private Byte[] sStringBytes;
    private String hash = string.Empty;

    /// <summary>
    ///  SStringV2 constructor
    /// </summary>
    /// <param name="confidentialData"></param>
    public SStringV2(ref Char[] confidentialData)
    {
        GCHandle charArrayHandle = GCHandle.Alloc(confidentialData, GCHandleType.Pinned);
        // The unmanaged string splices a zero byte inbetween every two bytes 
        //and at its end  doubling the total number of bytes
        sStringBytes = new Byte[confidentialData.Length*2];
        try
        {
            for (int index = 0; index < confidentialData.Length; ++index)
            {                   
                secureString.AppendChar(confidentialData[index]);
            }
        }
        finally
        {
            ZeroOutSequence.ZeroOutArray(ref confidentialData);
            charArrayHandle.Free();
        }
    }

    /// <summary>
    /// Computes the hash value of the secured string 
    /// </summary>
    private void GenerateHash()
    {
        IntPtr unmanagedRef = Marshal.SecureStringToBSTR(secureString);
        GCHandle byteArrayHandle = GCHandle.Alloc(sStringBytes, GCHandleType.Pinned);
        Marshal.Copy(unmanagedRef, sStringBytes, 0, sStringBytes.Length);
        SHA256Managed SHA256 = new SHA256Managed();

        try
        {
            hash = Convert.ToBase64String(SHA256.ComputeHash(this.sStringBytes));
        }
        finally
        {
            SHA256.Clear();
            ZeroOutSequence.ZeroOutArray(ref sStringBytes);
            byteArrayHandle.Free(); 
            Marshal.ZeroFreeBSTR(unmanagedRef);
        }
    }

    #region IEquatable<SStringV2> Members

    public bool Equals(SStringV2 other)
    {
        if ((this.hash == string.Empty) & ( other.hash == string.Empty))
        { 
            this.GenerateHash();
            other.GenerateHash();
        }
        else if ((this.hash == string.Empty) & !(other.hash == string.Empty))
        {
            this.GenerateHash();
        }
        else if (!(this.hash == string.Empty) & (other.hash == string.Empty))
        {
            other.GenerateHash();
        }

        if (this.hash.Equals(other.hash))
        {
            return true;
        }
            return false;
    }

    #endregion

    #region IDisposable Members

    public void Dispose()
    {
        secureString.Dispose();
        hash = string.Empty;
        GC.SuppressFinalize(this);
    }

    #endregion
}

}

Upvotes: 0

Views: 799

Answers (3)

Doug
Doug

Reputation: 5338

Don't forget that SecureString uses two-way encryption. I don't see any encryption in your class.

Upvotes: 1

RnR
RnR

Reputation: 2115

Just one quick note - You're asking for problems mistaking hash equality with data equality - sure the probability of them being different is low but once you hit it it'll be a nightmare :/ (I had the "luck" to debug and fix a custom hash-map implementation that made the same mistake a few years ago so please trust me on this ;) ).

Upvotes: 1

drscroogemcduck
drscroogemcduck

Reputation:

if you pass a char[] array in you start to lose the benefits of securestring. char[] array could be copied around in memory by the garbage collector before it is cleared.

Upvotes: 0

Related Questions