我正在从unencrypted检索MemoryStream密钥,将其转换为某种字符串,并使用该字符串与.NET的crypto函数加密数据。我需要确保unencrypted密钥在使用后从内存中删除。我找到了SecureString,我认为它将处理字符串,但我不知道如何在键成为SecureString之前清除它的内存。
所以每件事的运作方式是:
MemoryStream -> char[] -> SecureString
SecureString传递指向char数组的指针,那么当char数组完成时,它会擦除它吗?这是它的构造函数:
SecureString(Char*,int32)有一个实现它的这里的例子。
但是,一旦SecureString删除了数据(如果它擦除了数据),我仍然需要知道如何擦除MemoryStream中的数据,以及为了获得char[]而必须创建的任何中间对象。
这个问题可以归结为两部分:
如何将MemoryStream直接读入char[]而不产生内存中的任何其他内容?(如果这是不可能的,那么理想的过渡是什么?呃,MemoryStream -> string -> char[]?)
和,
当完成时,如何覆盖MemoryStream使用的内存(以及在MemStream->char[]进程中创建的任何其他签名)?
发布于 2015-06-11 19:26:37
首先,SecureString不会清除输入char*的内存--这是您的责任。它只会清理自己的内部存储器。
要将MemoryStream的内容读取/清除到本地char[]中,只需分配数组(假设流包含有效字符串):
// Get the contents of the stream.
var byKey = oMS.GetBuffer ();
fixed ( byte *pBytes = byKey )
{
var oSecStr = new SecureString ( (char*) pBytes,
(int) ( oMS.Length / 2 ) );
// Clear stream (there's no separate char/byte array
// to clean).
Array.Clear ( byKey, 0, byKey.Length );
}当然,这一切都假定为unsafe代码。然而,没有完全保证的方法可以从内存中清除所有密钥的潜在实例--在调用键进入流时,它可能会被多次复制(在各种您无法访问的私有缓冲区中),因此您可能甚至不知道周围有多少副本。
发布于 2015-06-11 19:29:53
你正在尝试的东西比你想象的更有问题。MemoryStream最有可能被其他东西使用,并且很有可能随着时间的推移而增大。
每增长一次,数据就会在内部复制到一个新数组中,旧数组被释放-- => --您的密钥可能会在这里泄漏。
另外,MemoryStream最有可能被其他API所使用。其他API很可能不会安全地删除密钥,因为它们的设计并不是这样做的。
但要回答您最初的问题:如果键只是ascii字符,您只需将字节复制到char数组中,然后用随机垃圾覆盖原始字节。您可以使用GetBuffer直接访问其内容。
https://stackoverflow.com/questions/30788666
复制相似问题