安全编辑控件






4.85/5 (19投票s)
2003年5月17日
5分钟阅读

145263

3781
安全编辑控件可防密码泄露。
引言
如今,安全性变得越来越重要。人们设计了非常安全的加密和认证算法(例如 AES、SHA)。但如果破解者通过利用操作系统简单的安全漏洞绕过这些系统,那么最优秀的算法也将毫无用处……
正如你可能已经想到的,我指的是 Windows 编辑控件。大多数“正常”的 Windows 程序都使用编辑控件来从用户那里获取密码。通常,当你在一个具有密码标志的编辑框中输入内容时,会看到星号(*)。不幸的是,这些编辑控件并不安全。存在各种方法供恶意程序和破解者获取密码。
第一种方法是简单地移除密码标志。Windows 对其他进程的窗口样式操作没有任何限制。只需移除编辑框的 ES_PASSWORD
标志,瞧!你就能看到输入的文本。
另一种方法是读出编辑框中的文本。对编辑控件使用 Windows API 函数 GetWindowText
,你就能获得文本,即使你不是该控件的所有者(即另一个进程),并且即使显示的是星号。
因此,我创建并向你展示一个控件,它非常用户友好(安全编辑控件看起来就像普通编辑控件),并且对这些间谍工具免疫,也就是说,上述方法在安全编辑控件上不起作用。
安全编辑控件的特性
这些是 CSecureEdit
类的特性
- 间谍无法读出安全编辑控件中的文本
- 移除
ES_PASSWORD
样式不会影响安全编辑控件 - 安全编辑控件看起来像普通的 Windows 编辑控件
- 用户可以在任何位置插入字符(例如,使用光标键)
- 用户可以删除一个或多个字符
- 用户可以将文本粘贴到安全编辑控件中
- 用户无法从安全编辑控件中复制文本
- MFC 开发者易于实现
技术背景
你想知道安全编辑控件是如何工作的吗?好的,我们开始吧。
安全编辑控件为实际文本和显示文本维护单独的缓冲区。显示文本只是密码字符乘以实际文本长度的结果。
每次用户按下一个键时,显示缓冲区都会包含一个非密码字符。现在是时候用密码字符替换该字符并更新内部的实际文本缓冲区了。
安全编辑控件是从 CEdit
派生的。它们会截获发送到编辑控件的 EN_UPDATE
消息,该消息会在控件内容更改时发送。该消息在 Windows 更新了其内容但尚未显示它之后发送。
CSecureEdit
类现在会检查发生了什么。用户是否插入了一个字符?是否使用 Del 或 Bkspc 删除了一个或多个字符?是否将文本粘贴到了控件中?首先,该类会计算旧文本和新文本的长度差。如果此差值小于 0,则表示用户已删除某些内容。
在这种情况下,我们必须查看光标所在的位置。现在,我们可以根据光标位置和差值信息,从内部缓冲区中删除已删除的文本。现在变得棘手了。如果用户选择了某些字符,比如 4 个,然后按了一个键,会怎样?差值为 3,删除了 4 个字符并输入了一个。在这种情况下,我们首先删除旧的 4 个字符,然后让字符插入例程在文本上运行。
在另一种情况(差值大于或等于零)下,用户已插入文本或用另一个字符(范围?)替换了一个字符(多个?剪贴板?)。插入相对容易。我们只需查看显示缓冲区并查找非密码字符。这些就是新输入的字符。现在需要做的就是比较显示缓冲区和内部实际文本缓冲区,并将显示缓冲区中的新字符插入到内部缓冲区中。最后,我们必须更新显示缓冲区,即用密码字符替换所有非密码字符。
使用安全编辑控件
实现 CSecureEdit
与实现其他自定义控件(如“平面”控件或彩色控件)一样简单。
只需按照这 4 个步骤将安全编辑控件包含到你的项目中
- 将文件 SecureEdit.cpp 和 SecureEdit.h 添加到你的项目中。
- 在 Visual Studio 的 Visual Resource Editor 中,创建一个普通的编辑控件。
- 右键单击编辑控件并选择 Class Wizard。
- 为控件创建一个类型为
CSecureEdit
的新成员变量
就是这样!你不需要调用任何初始化或配置函数。
要读取控件的实际文本,请读取 CSecureEdit
类的公共 CString
成员变量 m_strRealText
。在读取之前,你不需要调用 UpdateData
,控件会在用户更改任何内容时自动更新其文本。
要设置安全编辑控件的文本,请使用其成员函数 SetRealText
。
关于控件的一些说明
与普通编辑控件不同,你无法将输入到安全编辑控件的密码复制到剪贴板。但你*可以*将文本粘贴到控件中。在我看来,这是最合理的解决方案。允许粘贴,禁止复制。
你可以自由定义密码字符。但该字符不能由用户输入。目前使用的密码字符是一个特殊的 X。这不是普通的 X,而是 ASCII 码中较高的字符,用户通常不会输入它(他必须使用 ALT-XX 组合键才能插入它……)。因此,你不应使用标准的星号(*)或其他标准字符,如 ! ? - _ $ 或其他类似的字符……
现在,去下载一个或多个这些间谍程序,并在安全编辑控件上使用它们。你会发现这些间谍程序无法泄露输入到安全编辑控件的密码。
PwdSpy: http://www.codeguru.com/samples/pwdspy.html
Super Password Spy++: http://www.codeguru.com/ieprogram/SPwdSpy.html
历史
-
2003 年 5 月 29 日 - v1.2 -
CSecureEdit
类现在支持 Unicode,感谢 Steven Spencer 的支持 -
2003 年 5 月 18 日 - v1.1 - 修复了
SetRealText
函数中的一个 bug -
2003 年 5 月 17 日 - v1.0 - 首次正式发布
好了,就这样。现在去成为第一个发布带有防窗口间谍密码编辑功能的应用程序的人吧 :-)。