构建安全字符串类型的注意事项

时间:2009-03-12 14:30:34

标签: .net securestring

我已经开始构建一个安全的字符串类型 - 我称之为SecureStringV2 - 来扩展.Net框架中现有的SecureString类型。这种新类型将向现有类型添加一些基本功能(检查相等性,比较等),但仍保持SecureString类型提供的安全性,即在类型使用后清除内存中的所有内容。我计划使用Marshal类和哈希算法来实现这些功能。关于如何完成这项工作并完成正确的指示将不胜感激。你有没有看到我实施这个想法的任何问题?谢谢:))

更新:到目前为止,我的想法引领了我对图书馆核心课程的看法。看看,让我知道你的想法。

/// <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
}

}

3 个答案:

答案 0 :(得分:1)

只是一个简单的注释 - 你要问的问题是错误的哈希相等与数据相等 - 确保它们不同的可能性很低但是一旦你点击它就会成为一场噩梦:/(我有“运气”调试和修复几年前犯同样错误的自定义哈希映射实现,所以请相信我;))。

答案 1 :(得分:1)

不要忘记SecureString使用双向加密。我没有在你的班级看到任何加密。

答案 2 :(得分:0)

如果你传递一个char []数组,你开始失去了securestring的好处。 char []数组可以在清除之前由垃圾收集器在内存中复制。