安全字符串用法

本文关键字:用法 字符串 安全 | 更新日期: 2023-09-27 18:32:32

一篇文章使用了SecureString文本框控件(顺便说一句 http://weblogs.asp.net/pglavich/440191,这是好类吗?(。然后为了获取字符串值,它有这样的代码:

using (Crypto cryptor = new Crypto())
{
 IntPtr ptr = Marshal.SecureStringToBSTR(password);
 this.password = cryptor.EncryptString(Marshal.PtrToStringAuto(ptr)); 
 Marshal.ZeroFreeBSTR(ptr);
}
  • 当系统询问Marshal.PtrToStringAuto(ptr)也会创建一个字符串(应该不安全(,作者回答说它在using里面,string应该在那里呆一秒钟,然后被摧毁。我的问题是,这是真的吗?我想using关键词仅适用于加密对象,不是吗?为什么它适用于字符串?

  • 最后,假设我使用该SecureString文本框控件。并假设我有一些安全帮助程序方法,如Encrypt(string password, byte[] data),甚至Encrypt(byte [] key, byte [] data),将安全字符串(或安全字符串内容?(传递给该加密方法的安全方法是什么?

安全字符串用法

我的问题是,这是真的吗?我认为using关键字仅适用于 Crypto 对象,不是吗?为什么它适用于字符串?

没错:它不适用于类型 string .

using只是意味着一旦using块被留下,cryptor.Dispose()就会被调用,但cryptor绝对没有办法修改任何string对象,也不应该修改:这不是它的工作。

最后,假设我使用该SecureString文本框控件。假设我有一些安全助手方法,例如Encrypt(string password, byte[] data),甚至Encrypt(byte [] key, byte [] data),将安全字符串(或安全字符串内容?(传递给该加密方法的安全方法是什么?

使用Encrypt(string password, byte[] data)方法,这是不可能的。不能覆盖string对象的内容,因为字符串是不可变的,因此在对字符串进行垃圾回收之前,无法从内存中清除密码。一旦字符串垃圾回收,内存仍然不会被清除,你不再知道你需要清除什么内存。

有了Encrypt(byte[] key, byte[] data),这是可能的。

您首先必须固定数组(在填充其内容之前(,以便垃圾回收器无法在内存中移动它。您可以使用GCHandle.Alloc。确保通过GCHandleType.Pinned .这可确保密钥仅存在于内存中的单个位置。

这是您可以安全地传递给Encrypt方法的内容。

然后,在

完成该键后,可以将该数组中的所有字节重新设置为零。由于数组仍处于固定状态,因此可以确定密钥不存在于进程内存中的其他位置。

最后,不要忘记调用gcHandle.Free()以防止您的数组永远闲逛。

注意:还有其他处理SecureString的安全方法,但它们涉及指针,并且不是您给出的两个特定Encrypt签名的选项。

注2:这个答案的基本假设,以及一般的SecureString,是密码保存在内存中未加密的时间应该最小化。当代码未处理任何密码时,故障转储不应显示任何密码。SecureString 也没有解决其他合理的问题:您自己计算机上的恶意程序显然可以将代码注入您的进程,以与您自己的进程完全相同的方式解密字符串。这不是SecureString旨在解决的问题,我也不声称我在这个答案中描述的问题解决了它。