2

我只是想知道是否有一种有效的方法可以保护带有密码字符集的 TEdit 字段,这些工具可以从可以以纯文本形式读回的工具。

我认为这些工具例如抓取 TEdit 的目标句柄并使用 gettext 或类似的东西。

到目前为止,我尝试的是为存储在变量中的密码创建一个哈希,并将其写回 TEdit 丢失的焦点,但这对我来说没有意义,因为我需要存储另一个密码来计算里面的哈希的可执行文件。

也许有人对如何保护 TEdit 文本免受这些工具的影响有更好的了解。

4

3 回答 3

1

带有样式的编辑控件ES_PASSWORD可防止将其文本复制到剪贴板。剩下的就是拒绝向其他应用程序显示其窗口文本并将密码字符重置为空。后代类可以处理这些。

type
  TPasswordEdit = class(TEdit)
  protected
    procedure EmGetPasswordChar(var Message: TMessage); message EM_GETPASSWORDCHAR;
    procedure EmSetPasswordChar(var Message: TMessage); message EM_SETPASSWORDCHAR;
    procedure WMGetText(var Message: TMessage); message WM_GETTEXT;
  end;

procedure TPasswordEdit.EmGetPasswordChar(var Message: TMessage);
begin
  // for nirsoft's BulletsPassView, probably only prevents further inspection, 
  // injecting a thread perhaps - I have no idea what it's doing..
  if (PasswordChar = #0) or not InSendMessage then
    inherited;
end;

procedure TPasswordEdit.EmSetPasswordChar(var Message: TMessage);
begin
  if (PasswordChar <> #0) and (Message.WParam <> 0) then
    inherited;
end;

procedure TPasswordEdit.WMGetText(var Message: TMessage);
begin
  if (PasswordChar = #0) or not InSendMessage then // allow owning thread
    inherited;
end;
于 2016-06-20T18:58:13.217 回答
1

如果您真的只对通过从 TEdit 组件读取文本来防止其他程序提取密码感兴趣,那么我建议您改用 TMaskEdit ( http://docwiki.embarcadero.com/Libraries/Berlin/en/Vcl.Mask.TMaskEdit ) .

与 TEdit 不同,TMaskEdit 将原始文本存储在局部变量中,同时它可以显示不同格式的文本。这意味着这些程序总是会得到格式化的文本,而不是真正的密码文本。

但正如许多其他人所说,这不会为您提供太多保护,因为大多数恶意软件都依赖于按键记录方法,它们只是记录按下了哪些键。

愚弄他们的最佳选择是使用完全自定义的组件,它甚至不使用标准的 Windows 文本处理 API,因此他们甚至不知道何时输入密码。

于 2016-06-20T13:40:12.373 回答
-3

你可以做这样的事情。使用 ReadOnly=true 的普通编辑并隐藏您自己的密码。只有编辑中的内容是 *. 此示例适用于字母数字字符,但您可以轻松添加其他字符。此外,如果您想在编辑中使用选择,您也需要处理它。

代码:

uses
  StrUtils;

var
  password: String;

...

procedure TForm1.FormCreate(Sender: TObject);
begin
  password:='';
end;

...

procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
var sel: Integer;
begin
  sel:=Edit1.SelStart;
  if((Key>=48) and (Key<=90))then
  begin
    if(ssShift in Shift)then
      password:=LeftStr(password, sel)+Char(Key)+RightStr(password, Length(Edit1.Text)-sel)
    else
      password:=LeftStr(password, sel)+LowerCase(Char(Key))+RightStr(password, Length(Edit1.Text)-sel);

    Edit1.Text:=Edit1.Text+'*';
    Edit1.SelStart:=sel+1;
  end
  else if((Key>=VK_NUMPAD0) and (Key<=VK_NUMPAD9))then
  begin
    password:=LeftStr(password, sel)+Char(Key-48)+RightStr(password, Length(Edit1.Text)-sel);
    Edit1.Text:=Edit1.Text+'*';
    Edit1.SelStart:=sel+1;
  end
  else if((Key=VK_BACK) and (sel>0))then
  begin
    Delete(password, sel, 1);
    Edit1.Text:=Copy(Edit1.Text, 1, Length(Edit1.Text)-1);
    Edit1.SelStart:=sel-1;
  end
  else if((Key=VK_DELETE) and (sel<Length(Edit1.Text)))then
  begin
    Delete(password, sel+1, 1);
    Edit1.Text:=Copy(Edit1.Text, 1, Length(Edit1.Text)-1);
    Edit1.SelStart:=sel;
  end
  else if(Key=VK_RETURN)then
  begin
    //handle the password check here (make hash etc)
    ShowMessage(password);
    password:='';
    Edit1.Text:='';
  end;

  //just for the testing, this should be removed of course
  Form1.Caption:=password;
end;
于 2016-06-20T08:36:08.417 回答