清除C#中的System.String

时间:2013-11-06 10:27:06

标签: c#

这会覆盖我的字符串的内容:

unsafe
{
    fixed (char* chars = str)
    {
        for (int i = 0; i < str.Length; i++)
            chars[i] = '1';
    }
}

背景是我正在使用NetworkCredientials,您可以使用普通的System.String设置密码。如果可能的话,之后我想“清除它”。有关如何执行此操作的任何建议都是受欢迎的,但主要问题是要了解fixed是否真的允许我访问底层char数组。谢谢!

修改

我想了解 在这里发生了什么 - 如果字符串对象是不可变的,并且fixed不让对象移动那么发布的代码中发生了什么?这些字符写在哪里?

3 个答案:

答案 0 :(得分:12)

请改用NetworkCredentials constructor overload taking SecureString。过载的全部原因是为了避免这个问题。你不应该试图改变System.String实例。 (这当然可以通过反思,但应该避免。)

答案 1 :(得分:6)

System.String是不可变的,因此您无法对其进行修改。

From MSDN:

  

字符串是不可变的 - 字符串对象的内容不能   在创建对象后更改,尽管语法可以实现   好像你可以这样做。

如果出于安全原因需要删除字符串,请尝试查看SecureString

事实上,你的代码改变了字符串,你可以在这里看到Eric Lippert的回答:String immutability in C#

  

您可以创建CLR在其上强制实现不变性的类型。您   然后可以使用“不安全”来关闭CLR执行机制。   这就是为什么“不安全”被称为“不安全” - 因为它关闭了   安全系统。在不安全的代码中的每个字节的内存   如果你足够努力,包括两者都可以写进程   不可变字节和CLR中强制不变性的代码。

如果你真的只限于没有SecureString的C#版本,那么你必须使用不安全的代码。但也许最好的解决方案是更加努力地改变版本。

答案 2 :(得分:2)

  

我想了解这里发生了什么 - 如果一个字符串对象是不可变的,并且修复了不让对象移动那么发布的代码中发生了什么?这些字符写在哪里?

如果按照规则玩,字符串只是不可变的。在这里,您实际上是通过使用不安全的代码来改变字符串。 (甚至可以使代码在传递peverify的意义上是“安全的”,但是以其他方式使规则弯曲,例如通过反射调用非公共AppendInPlace方法或{{} 3}}。)

违反这样的规则是危险的。它可能干扰abusing union structs。它可能会破坏.NET运行时所依赖的内存位置,例如每个.NET对象开头存在的TypeHandle和syncblk字节。等