是否可以清除窗体文本框中的内存?

Posted

技术标签:

【中文标题】是否可以清除窗体文本框中的内存?【英文标题】:Is it possible to clear out the memory in the window form text box? 【发布时间】:2012-02-14 16:34:59 【问题描述】:

我有一个程序可以检测用户的用户名和域,用户必须输入密码才能进入主程序。我立即阅读了将其设置为安全字符串的密码,然后清除了文本框。我正在使用窗口窗体。

有人告诉我,我仍然需要“在读取密码后将内存清零”。我很难找到在程序结束之前将内存清零的方法。

这是我处理密码的代码的一部分:

.....
                        domainName = txtDomain.Text;
                        userName = txtUsername.Text;
                        SecureString securePwd = ConvertToSecureString(txtPassword.Text);
                        txtPassword.Clear();
                        txtPassword.Dispose();

                        rSP.setUp();
                        // If the username or/and password is incorrect the user need to go back to fill it in again. 
                        if (verify == false)
                            CheckAuthentication("http://xxxx/xxxx/default.aspx", userName, securePwd, domainName);
                        if (verify == true)
                        
                            ....
                         
    .... 

我知道这是将内存归零的坏方法。

当我运行调试时,我唯一能看到密码纯文本的地方是当我将它传递给 SecureString securePwd = ConvertToSecureString(txtPassword.Text); 并且在我清除文本框 txtPassword.Clear(); 之前

如果您能帮我解决这个问题,我将不胜感激。

【问题讨论】:

这个答案可以帮助你理解这个概念:***.com/questions/8881291/… @JamesShuttler 好吧,我不能使用 Character 来存储我的密码,因为我正在使用文本框。如果我开始将密码转换为字符,那么它将在内存中暴露更多。另外,我有安全字符串,可以将字符串转换为加密字符。 【参考方案1】:

你正在与你想要完成的事情进行一场失败的战斗。如果您想要安全性,请使用一种语言(或控件)来促进您在本地追求的目标(这会为您带来更多的工作)。尽管如此,总会有(更简单的)方法来捕获在读取内存之外输入到文本框中的内容,因此擦除文本框内存是没有意义的,除非您可以以某种方式证明客户端机器是干净且值得信赖(在这种情况下,您的问题毫无用处)。

如果您可以保证客户端的环境没有键盘记录器和窗口嗅探器,但由于某种原因您仍然对此感到担忧,那么我建议您编写一些 可能 em> 能够使用类似于您试图避免的程序的技术将内存归零。即使在这种情况下,您也不能保证数据安全,因为从将密码输入文本框到提交表单,总有一段时间它会以纯文本形式出现在内存中。

如果你不得不问你是怎么做的,那么你可能一开始就不应该这样做,即使我们这些天真地尝试过的人也没有在没有陷阱的情况下这样做。

更新

经过进一步思考,您可以通过以下方式执行您的操作(保存涉及键盘记录器的情况):

1. Keeping track of encrypted keys pressed in some sort of collection
2. Hooking one of the key press events on the textbox whose event handler would:
  2a. Encrypt each key value using an asymmetric encryption
  2b. Add it to the encrypted key collection
  2c. Add an explicit password character to the textbox (or not depending on your requirements)
  2d. Explicitly tell the event to ignore the key

虽然这样做所需的工作量可能超过威胁(特别是考虑到它不能防范键盘记录器)。在您的情况下,这也将否定 SecureString 的必要性。

【讨论】:

【参考方案2】:

...然后呢?那么如果字符串在内存中呢?您是否担心用户机器上的程序可以从内存中读取它?该程序可能是键盘记录器。

如果程序在用户的机器上运行,并且用户已经登录,那么程序已经可以访问网络,就好像它是那个用户一样。您只是碰巧重新使用验证方法来限制对程序的访问。但是如果目标机器感染了某个程序,可以在你的程序执行期间读取内存,那么它可以在程序的整个执行过程中读取你程序的内存

查看本系列文章The Old New Thing。

【讨论】:

是的,显然我的同事认为可以从内存中读取用户的机器,或者某些黑客可以访问内存并读取密码。 他们绝对可以。但这只是你的问题之一,也不是最严重的问题。 @Matt Dawdy:有人可能会说,对于攻击者来说,让事情变得更简单是没有意义的,所以试图实现的目标是有价值的。以这种方式减少了获取敏感数据的机会窗口。你会不会因为你知道一个附件可以移除硬盘驱动器并通过插入它而不是另一台电脑来访问它上的所有内容而用未加密的硬盘驱动器锁定你的计算机?你不会,因为为什么要让攻击者的事情变得更简单。 更多安全的家比更少安全的家更好,即使安全性不是绝对的。 @zespri 我认为你没有抓住重点。如果攻击者可以检查我机器上运行的程序的内存,那么他们也可以记录我的击键并通过这种方式获取我的密码。他们可以窃取/破坏我机器上的数据以及我可以访问的任何网络驱动器。他们可以从我的浏览器中窃取我的密码。这就像一个强盗进入你的家并拿走你的钱包,但你的信用卡号码写在一张纸上,而你正试图保护那张纸。谁在乎?他已经拿到信用卡了。 @Matt Dawdy:实际上是我试图指出你没有抓住重点,不幸的是我没有成功。这是非常黑白的世界观。这当然有助于 Raymond Chen 的团队从虚假问题中剔除真正的安全问题,但对于手头的案例而言,它的用处要小得多。假设由于您的机器受到破坏,内存和磁盘上的所有内容都会神奇地转移给攻击者,这有点天真。这是不切实际的。如果攻击者知道他在追求什么,那么是的,你是对的,你完蛋了。但在许多情况下,他没有。所以每一点都有帮助【参考方案3】:

一些建议是:

由于内存可以存储在硬盘上,因此您应该 考虑在您的文本框中放置一个随机字符串以使其 覆盖而不是清除您的文本框。硬盘是这样的 清洁工具工作。问题陈述了内存,但.NET可以使用 硬盘存储(如果需要),Windows 也可以(但这似乎是 牵强的场景)。

您还应该确保您的课程是密封的,并且您的 签署的程序集试图使您的班级免受其他人的侵害 将您的代码用作库。

您也可以考虑通过删除完全绕过 Textbox.text 键入的每个字符。然后把收集到的信息,即 击键或粘贴操作到双向加密存储中。这 方法需要大量自定义代码,所以可能不是 更可取。

【讨论】:

将新数据写入文本框将没有帮助;它创建了一个全新的字符串对象。 好点。字符串是不可变的。我建议改为存储输入的字符。 ...不过,这是我的首先想到的。呵呵 我给了你+1哈哈。【参考方案4】:

我知道这是很久以前问过的,但我想我会给出我的解决方案,以防有人像我一样偶然发现它。

我通过使用 WindowsForms 并为常规文本框(而不是密码框)捕获 KeyPress 事件来实现这一点。我没有让事件填充文本框,而是生成了一个“*”字符并将该字符直接插入到 SecureString 中。这样密码就永远不会在内存中......在大多数情况下......

首先触发KeyDown:

private void Password_KeyDown(object sender, KeyEventArgs e)
    
        TextBox caller = sender as TextBox;

        int position = caller.SelectionStart;

        _PasswordBoxControlDown = e.Control;  // toggle if control is also down

        switch (e.KeyCode)
        
            case Keys.Delete: //delete pressed
                if (caller.SelectionLength > 0)  //more than 1 character selected
                
                    for (int i = caller.SelectionStart; i < caller.SelectionStart + caller.SelectionLength; i++)
                        _SecurePassword.RemoveAt(caller.SelectionStart);   //remove from secure password

                    caller.Text = caller.Text.Remove(caller.SelectionStart, caller.SelectionLength); //update textbox to reflect number of characters
                    KeyDownDidSomething(caller, e, position);
                
                else if (caller.SelectionStart < caller.Text.Length) // nothing selected - but cursor is not at the end of textbox
                
                    _SecurePassword.RemoveAt(caller.SelectionStart);
                    caller.Text = caller.Text.Remove(caller.SelectionStart, 1);
                    KeyDownDidSomething(caller, e, position);
                

                break;
            case Keys.Back: //backspace pressed
                if (caller.SelectionLength > 0) //more than 1 character selected
                
                    for (int i = caller.SelectionStart; i < caller.SelectionStart + caller.SelectionLength; i++)
                        _SecurePassword.RemoveAt(caller.SelectionStart); //remove from secure password

                    caller.Text = caller.Text.Remove(caller.SelectionStart, caller.SelectionLength); //update textbox to reflect number of characters
                    KeyDownDidSomething(caller, e, position);
                
                else if (caller.SelectionStart > 0) // nothing selected - but cursor is not at the beginning of textbox
                
                    _SecurePassword.RemoveAt(caller.SelectionStart - 1);
                    caller.Text = caller.Text.Remove(caller.SelectionStart - 1, 1);
                    position--;
                    KeyDownDidSomething(caller, e, position);
                
                break;
        

     

        e.Handled = true; //tells the text box that the event has been handled, text box will not write character to text box.
        caller.SelectionLength = 0;
    

    private void KeyDownDidSomething(TextBox caller, KeyEventArgs e, int position)
    
        //use this to do whatever you need to do when you handle an event (if at all)
    

后跟按键

private const char ENTER_KEY = (char)13;
private const char CNTRL_V = (char)22;

private void Password_KeyPress(object sender, KeyPressEventArgs e)
    
        TextBox caller = sender as TextBox;

        char ch = e.KeyChar;
        int position = caller.SelectionStart;

        if (ch >= 32 && ch <= 126) //acceptable password symbol
        
            int len = caller.SelectionLength;
            if (caller.SelectionLength > 0) //Handles inserting when text is selected (removing selected characters)
            
                for (int i = caller.SelectionStart; i < caller.SelectionStart + caller.SelectionLength; i++)
                    _SecurePassword.RemoveAt(caller.SelectionStart);

                caller.Text = caller.Text.Remove(caller.SelectionStart, caller.SelectionLength);
            

            _SecurePassword.InsertAt(position, ch);
            caller.Text = caller.Text + '*'; //generate a * so the user knows how many characters they've entered
            caller.SelectionStart = position + 1;
        
        else //handle other symbol
        
            switch (ch)
            
                case CNTRL_V:
                    Password_PasteClicked(null, null); //handle paste event
                    break;

                case ENTER_KEY:
                    SaveAndCloseButton_Click(null, null); //handle enter .. if you want to.
                    break;

              //add events for any special characters here
                 
        

有点让人觉得它在密码框中保存了密码。无论如何,当你完成密码时抛出一个 _SecurePassword.Dispose()。

【讨论】:

以上是关于是否可以清除窗体文本框中的内存?的主要内容,如果未能解决你的问题,请参考以下文章

selenium怎样清除文本框中输入的内容

vb窗体程序运行时,文本框中的默认的文字怎么设置为空

在 c# 中使用文本框中的数据库值打开特定的 Windows 窗体

如何通过在 C# windows 窗体中的文本框中输入来更改图像的大小?

vb中图片框如何清除里面的所有内容?

如何从html中的文本框中清除搜索输入? [复制]