有一篇文章是使用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关键字只适用于Crypto对象,不是吗?为什么它适用于字符串?SecureString文本框控件。假设我有一些安全助手方法,比如Encrypt(string password, byte[] data),甚至Encrypt(byte [] key, byte [] data),那么传递安全字符串(或安全字符串内容)的安全方法是什么?加密的方法?发布于 2014-11-29 22:43:38
我的问题是,这是真的吗?我以为
using关键字只适用于Crypto对象,不是吗?为什么它适用于字符串?
这是正确的:它不适用于string类型。
using只是意味着cryptor.Dispose()将在using块离开后被调用,但是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设计用来解决的问题,我也不认为我在这个答案中描述的问题解决了它。
https://stackoverflow.com/questions/27207490
复制相似问题