Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/261.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用C#中的指针安全地清除文本框的内容?_C#_.net_Winforms_Security_Pointers - Fatal编程技术网

如何使用C#中的指针安全地清除文本框的内容?

如何使用C#中的指针安全地清除文本框的内容?,c#,.net,winforms,security,pointers,C#,.net,Winforms,Security,Pointers,我目前正在尝试在Windows窗体中创建一个密码存储系统,我听说一旦使用完,就应该尽快覆盖包含敏感信息的字符串。由于字符串在C#中是不可变的,所以我决定尝试使用指针清除包含用户名和密码的两个TextBoxes。我尝试了两种方法(OP的方法和公认的答案),但它们似乎都无法清除文本框中的文本(尽管它们适用于普通字符串);我在网上也找不到更多的答案。这是一个预期的特性,还是我在代码中做错了什么?我的方法是不是太过分了?我的方法根本不管用吗 代码: //我尝试的第一个方法 不安全的 { if(this.

我目前正在尝试在Windows窗体中创建一个密码存储系统,我听说一旦使用完,就应该尽快覆盖包含敏感信息的字符串。由于字符串在C#中是不可变的,所以我决定尝试使用指针清除包含用户名和密码的两个
TextBox
es。我尝试了两种方法(OP的方法和公认的答案),但它们似乎都无法清除
文本框中的文本(尽管它们适用于普通字符串);我在网上也找不到更多的答案。这是一个预期的特性,还是我在代码中做错了什么?我的方法是不是太过分了?我的方法根本不管用吗

代码:

//我尝试的第一个方法
不安全的
{
if(this.textBox1.Text!=String.Empty)
已修复(char*usr=this.textBox1.Text)
for(int i=0;i

编辑:如果有人想知道,我使用的是.NET Framework 4.8。

通常,内存中的数据可能包含敏感数据。程序操作的所有数据都需要在某个时刻存储在内存中,因此内存中当然也有敏感数据(不仅是密码,当然还有使用此密码获取的数据、用户名、电子邮件地址等)。一旦不再使用数据,就可以(或多或少地)将其从内存中删除,但这并不能真正解决问题,它可能只会降低数据泄漏的风险

但是,正如我在上面的评论中所说的,如果有人访问程序内存,安全性就会受到威胁,他或她可以对程序数据做任何想做的事情,也可以在活动用户的权限下开始执行任务

在Windows上,通常允许调试自己的程序,因此在计算机上执行的任何程序(理论上)都可以从同一用户拥有的任何其他正在运行的程序中读取所有数据,因为调试意味着读取和写入程序的内存。或多或少,防止这种情况的唯一方法是防止电脑受到恶意软件的感染


这完全独立于所使用的程序语言。

因为字符串在C#
中是不可变的,正确,但是覆盖它们或指定新值将不会产生任何影响;你仍然可以读取内存。问题是你想用它实现什么。如果有人(或某个软件)能够读取应用程序的进程内存,那么无论如何,您都会丢失。那里有这么多敏感数据,泄露密码将是你的最小问题。在这种情况下,你也可以执行任意代码。另一方面,你可以使用,我认为你的解决方案会达到你期望的效果。您是否测试过它(即使用调试器),或者为什么您认为它不起作用?@Codexer嗯,我认为覆盖内存地址会忽略字符串的不变性;我链接的帖子的答案暗示了这一点。因此,一个程序试图搜索被GC不正确清除的内存的风险在技术上与试图在运行时破坏内存的程序类型相同,这对于程序作者来说是不可预防的;我现在明白了。是的,这正是重点。当然,这意味着您的程序本身没有明显的数据泄漏(比如通过网络以明文形式发送密码)
// First method that I tried
unsafe
{
    if (this.textBox1.Text != String.Empty)
        fixed (char* usr = this.textBox1.Text)
            for (int i = 0; i < this.textBox1.Text.Length; i++)
                usr[i] = '\0';
    if (this.textBox2.Text != String.Empty)
        fixed (char* pwd = this.textBox2.Text)
            for (int i = 0; i < this.textBox2.Text.Length; i++)
                pwd[i] = '\0';
}

// Second method that I tried
if (this.textBox1.Text != String.Empty)
{
    GCHandle gcU = GCHandle.Alloc(this.textBox1.Text, GCHandleType.Pinned);
    unsafe
    {
        char* usr = (char*)gcU.AddrOfPinnedObject();
        for (int i = 0; i < this.textBox1.Text.Length; i++)
            usr[i] = '\0';
    }
    gcU.Free();
}
if (this.textBox2.Text != String.Empty)
{
    GCHandle gcP = GCHandle.Alloc(this.textBox1.Text, GCHandleType.Pinned);
    unsafe
    {
        char* pwd = (char*)gcP.AddrOfPinnedObject();
        for (int i = 0; i < this.textBox2.Text.Length; i++)
            pwd[i] = '\0';
    }
    gcP.Free();
}