如何防止文本框中加密的字符被窃取??
2007-07-16 15:38
417 查看
使用了文本框后:防止 软件读取 文本框中 TEXT
在WINDOWS下的密码输入框一般都是以 “*” 来显示密码的,而有许多工具软件可以窃取密码,下面我就分析下如何防止“*” 密码泄露。
1. 取同一程序密码框中的内容
一般我们的密码框用 TEDIT 的PasswordChar 属性为 “*”,首先还是了解下EDIT1.TEXT 取文本框内容的原理。在DELPHI
中可以知道TEDIT继承自TCustomEdit,而TCustomEdit 继承自TControl. TControl中的Property Text是调用Gettext,而,GetText
调用了GetTextBuf,GetTextBuf 调用了Perform(SendMessage)最终实现了读取Edit中的内容。
关键代码可以在DELPHI的Controls.pas 和StdCtrls.pas文件中看到。
property Text: TCaption read GetText write SetText;
function TControl.GetText: TCaption;
var
Len: Integer;
begin
Len := GetTextLen;
SetString(Result, PChar(nil), Len);
if Len <> 0 then GetTextBuf(Pointer(Result), Len + 1);
end;
function TControl.GetTextBuf(Buffer: PChar; BufSize: Integer): Integer;
begin
Result := Perform(WM_GETTEXT, BufSize, Longint(Buffer));
end;
通过看代码可以知道要获得Edit1的内容可以用下面的语句:
SendMessage(Edit1.handle,WM_GETTEXT,i,integer(buffer));
其中,buffer是PCHAR类型,用于存放Edit1中的内容,i 是buffer的空间大小。
示例代码如下:
procedure TForm1.Button1Click(Sender: TObject);
var
buffer:PChar;
L:integer;
begin
L:=GetWindowTextLength(Edit1.handle);
GetMem(buffer,L+1);
SendMessage(Edit1.handle,WM_GETTEXT,L,integer(buffer));
label1.Caption:=String(buffer);
FreeMem(buffer);
end;
实际使用 SendMessage(Edit1.handle,WM_GETTEXT,L,integer(Name));语句可以用
GetWindowText(Edit1.handle,buffer,L);代替,GetWindowText 是Windows API函数
这是在本地程序中取密码,如果在其他程序中取密码框中的内容时,必须先用各种方法取的密码框的句柄
再用SendMessage取的密码框的内容,为了保证通用性比较常用的办法是用鼠标钩子取鼠标当前位置的控件
句柄。具体的实现方法,在我的另外的读书笔记“钩子”中可以看到。
2.如何防范密码框密码泄露
现在软件的登陆密码时间上是一种很脆弱的安全防范方式,除了用上面说的方法窃取到,还可以用
更简单的办法可以得到,那就是用SendMessage向密码框发送一个EM_GETPASSWORDCHAR消息,将Passwordchar
设置为#0,就可以让密码显示出来,所以对重要的密码加上一曾保护是必要的。
因为现在的WINDOWS下的开发工具编写密码框时都是调用了WINDOWS系统编辑框,所以为了避免这种情况,一个
简单的饿办法就是子类化(Subclassing),也就是使用自己自定义的编辑框,并使字定义的WindowProc来进行消息
处理,对 Passwordchar的设置和文本读取消息(分别是EM_SETPASSWORDCHAR和WM_GETTEXT)进行检查,把那些
非法操作过滤掉,下面的子类化的TPasswordEdit完全过滤了以上两个消息,其基本原则是在密码框的消息处理
函数中使用一个变量(见下例中的FAllowPasswordRead或FAllowPasswordCharChange)来标志是否是自己的代码
如果是来历不明的代码试图设置passwordchar或读取文本,就不给它返回任何数值。
代码如下:
type
TPasswordEdit = class(TEdit) //建立新的控件
private
FFalsePassword: TCaption;
FAllowPasswordRead: Boolean;
FAllowPasswordCharChange: Boolean;
function GetPasswordChar: Char;
function GetText: TCaption;
procedure SetPasswordChar(const Value: Char);
procedure SetText(const Value: TCaption);
public
constructor Create(AOwner: TComponent); override;
procedure DefaultHandler(var Message); override;
published
property AllowPasswordCharChange: Boolean read FAllowPasswordCharChange write FAllowPasswordCharChange;
property AllowPasswordRead: Boolean read FAllowPasswordRead write FAllowPasswordRead;
property PasswordChar: Char read GetPasswordChar write SetPasswordChar default '*';
property FalsePassword: TCaption read FFalsePassword write FFalsePassword;
property Text: TCaption read GetText write SetText;
end;
TForm1 = class(TForm)
Edit1: TEdit;
Label1: TLabel;
Label2: TLabel;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
PasswordEdit1: TPasswordEdit;
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
constructor TPasswordEdit.Create(AOwner: TComponent);
begin
AllowPasswordCharChange := true;
AllowPasswordRead := true;
inherited Create(AOwner);
AllowPasswordCharChange := false;
AllowPasswordRead := false;
PasswordChar := '*'; {显示*}
end;
procedure TPasswordEdit.SetPasswordChar(const Value: Char);
var
OldAPCC, OldAPR: boolean;
begin
OldAPCC := FAllowPasswordCharChange;
OldAPR := FAllowPasswordRead;
FAllowPasswordCharChange := true;
FAllowPasswordRead := true;
if HandleAllocated then
inherited PasswordChar := Char(Sendmessage(Handle, EM_GETPASSWORDCHAR, 0, 0));
inherited PasswordChar := Value;
FAllowPasswordCharChange := OldAPCC;
FAllowPasswordRead := OldAPR;
end;
function TPasswordEdit.GetPasswordChar: Char;
begin
if HandleAllocated then
Result := Char(Sendmessage(Handle, EM_GETPASSWORDCHAR, 0, 0))
else
Result := inherited PasswordChar;
end;
procedure TPasswordEdit.SetText(const Value: TCaption);
begin
inherited Text := Value;
end;
function TPasswordEdit.GetText: TCaption;
var
OldAPCC, OldAPR: boolean;
begin
OldAPCC := FAllowPasswordCharChange;
OldAPR := FAllowPasswordRead;
FAllowPasswordCharChange := true;
FAllowPasswordRead := true;
Result := inherited Text;
FAllowPasswordCharChange := OldAPCC;
FAllowPasswordRead := OldAPR;
end;
procedure TPasswordEdit.DefaultHandler(var Message);
var
P: PChar;
begin
if (csDesigning in ComponentState) or (csCreating in ControlState) then
inherited //如果在程序设计和正在建立阶段不需要做任何变动
else
with TMessage(Message) do
case msg of
EM_SETPASSWORDCHAR: if FAllowPasswordCharChange then
inherited; //如果允许设置EM_SETPASSWORDCHAR才可以继续
WM_GETTEXT: if FAllowPasswordRead then inherited
else begin
P := PChar(FFalsePassword);
Result := StrLen(StrLCopy(PChar(LParam), P, WParam - 1));
end; //如果允许读文本才可以继续否则返回(FFalsePassword)的长度
WM_GETTEXTLENGTH: if FAllowPasswordRead then inherited
else
if PChar(FFalsePassword) = nil then Result := 0
else Result := StrLen(PChar(FFalsePassword)); //如果允许读文本 才可以继续否则返回0或位密码
else
inherited;
end
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
PasswordEdit1 := TPasswordEdit.Create(self);
PasswordEdit1.parent := form1;
PasswordEdit1.Width := 150;
PassWordEdit1.Height := 21;
PasswordEdit1.Top := 115;
PasswordEdit1.Left := 80;
PasswordEdit1.PasswordChar := '*';
PasswordEdit1.AllowPasswordRead := false;
PasswordEdit1.Visible := true;
PasswordEdit1.Text:='Hello';
PasswordEdit1.FalsePassword:= '想读我?没门!'
end;
end.
在WINDOWS下的密码输入框一般都是以 “*” 来显示密码的,而有许多工具软件可以窃取密码,下面我就分析下如何防止“*” 密码泄露。
1. 取同一程序密码框中的内容
一般我们的密码框用 TEDIT 的PasswordChar 属性为 “*”,首先还是了解下EDIT1.TEXT 取文本框内容的原理。在DELPHI
中可以知道TEDIT继承自TCustomEdit,而TCustomEdit 继承自TControl. TControl中的Property Text是调用Gettext,而,GetText
调用了GetTextBuf,GetTextBuf 调用了Perform(SendMessage)最终实现了读取Edit中的内容。
关键代码可以在DELPHI的Controls.pas 和StdCtrls.pas文件中看到。
property Text: TCaption read GetText write SetText;
function TControl.GetText: TCaption;
var
Len: Integer;
begin
Len := GetTextLen;
SetString(Result, PChar(nil), Len);
if Len <> 0 then GetTextBuf(Pointer(Result), Len + 1);
end;
function TControl.GetTextBuf(Buffer: PChar; BufSize: Integer): Integer;
begin
Result := Perform(WM_GETTEXT, BufSize, Longint(Buffer));
end;
通过看代码可以知道要获得Edit1的内容可以用下面的语句:
SendMessage(Edit1.handle,WM_GETTEXT,i,integer(buffer));
其中,buffer是PCHAR类型,用于存放Edit1中的内容,i 是buffer的空间大小。
示例代码如下:
procedure TForm1.Button1Click(Sender: TObject);
var
buffer:PChar;
L:integer;
begin
L:=GetWindowTextLength(Edit1.handle);
GetMem(buffer,L+1);
SendMessage(Edit1.handle,WM_GETTEXT,L,integer(buffer));
label1.Caption:=String(buffer);
FreeMem(buffer);
end;
实际使用 SendMessage(Edit1.handle,WM_GETTEXT,L,integer(Name));语句可以用
GetWindowText(Edit1.handle,buffer,L);代替,GetWindowText 是Windows API函数
这是在本地程序中取密码,如果在其他程序中取密码框中的内容时,必须先用各种方法取的密码框的句柄
再用SendMessage取的密码框的内容,为了保证通用性比较常用的办法是用鼠标钩子取鼠标当前位置的控件
句柄。具体的实现方法,在我的另外的读书笔记“钩子”中可以看到。
2.如何防范密码框密码泄露
现在软件的登陆密码时间上是一种很脆弱的安全防范方式,除了用上面说的方法窃取到,还可以用
更简单的办法可以得到,那就是用SendMessage向密码框发送一个EM_GETPASSWORDCHAR消息,将Passwordchar
设置为#0,就可以让密码显示出来,所以对重要的密码加上一曾保护是必要的。
因为现在的WINDOWS下的开发工具编写密码框时都是调用了WINDOWS系统编辑框,所以为了避免这种情况,一个
简单的饿办法就是子类化(Subclassing),也就是使用自己自定义的编辑框,并使字定义的WindowProc来进行消息
处理,对 Passwordchar的设置和文本读取消息(分别是EM_SETPASSWORDCHAR和WM_GETTEXT)进行检查,把那些
非法操作过滤掉,下面的子类化的TPasswordEdit完全过滤了以上两个消息,其基本原则是在密码框的消息处理
函数中使用一个变量(见下例中的FAllowPasswordRead或FAllowPasswordCharChange)来标志是否是自己的代码
如果是来历不明的代码试图设置passwordchar或读取文本,就不给它返回任何数值。
代码如下:
type
TPasswordEdit = class(TEdit) //建立新的控件
private
FFalsePassword: TCaption;
FAllowPasswordRead: Boolean;
FAllowPasswordCharChange: Boolean;
function GetPasswordChar: Char;
function GetText: TCaption;
procedure SetPasswordChar(const Value: Char);
procedure SetText(const Value: TCaption);
public
constructor Create(AOwner: TComponent); override;
procedure DefaultHandler(var Message); override;
published
property AllowPasswordCharChange: Boolean read FAllowPasswordCharChange write FAllowPasswordCharChange;
property AllowPasswordRead: Boolean read FAllowPasswordRead write FAllowPasswordRead;
property PasswordChar: Char read GetPasswordChar write SetPasswordChar default '*';
property FalsePassword: TCaption read FFalsePassword write FFalsePassword;
property Text: TCaption read GetText write SetText;
end;
TForm1 = class(TForm)
Edit1: TEdit;
Label1: TLabel;
Label2: TLabel;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
PasswordEdit1: TPasswordEdit;
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
constructor TPasswordEdit.Create(AOwner: TComponent);
begin
AllowPasswordCharChange := true;
AllowPasswordRead := true;
inherited Create(AOwner);
AllowPasswordCharChange := false;
AllowPasswordRead := false;
PasswordChar := '*'; {显示*}
end;
procedure TPasswordEdit.SetPasswordChar(const Value: Char);
var
OldAPCC, OldAPR: boolean;
begin
OldAPCC := FAllowPasswordCharChange;
OldAPR := FAllowPasswordRead;
FAllowPasswordCharChange := true;
FAllowPasswordRead := true;
if HandleAllocated then
inherited PasswordChar := Char(Sendmessage(Handle, EM_GETPASSWORDCHAR, 0, 0));
inherited PasswordChar := Value;
FAllowPasswordCharChange := OldAPCC;
FAllowPasswordRead := OldAPR;
end;
function TPasswordEdit.GetPasswordChar: Char;
begin
if HandleAllocated then
Result := Char(Sendmessage(Handle, EM_GETPASSWORDCHAR, 0, 0))
else
Result := inherited PasswordChar;
end;
procedure TPasswordEdit.SetText(const Value: TCaption);
begin
inherited Text := Value;
end;
function TPasswordEdit.GetText: TCaption;
var
OldAPCC, OldAPR: boolean;
begin
OldAPCC := FAllowPasswordCharChange;
OldAPR := FAllowPasswordRead;
FAllowPasswordCharChange := true;
FAllowPasswordRead := true;
Result := inherited Text;
FAllowPasswordCharChange := OldAPCC;
FAllowPasswordRead := OldAPR;
end;
procedure TPasswordEdit.DefaultHandler(var Message);
var
P: PChar;
begin
if (csDesigning in ComponentState) or (csCreating in ControlState) then
inherited //如果在程序设计和正在建立阶段不需要做任何变动
else
with TMessage(Message) do
case msg of
EM_SETPASSWORDCHAR: if FAllowPasswordCharChange then
inherited; //如果允许设置EM_SETPASSWORDCHAR才可以继续
WM_GETTEXT: if FAllowPasswordRead then inherited
else begin
P := PChar(FFalsePassword);
Result := StrLen(StrLCopy(PChar(LParam), P, WParam - 1));
end; //如果允许读文本才可以继续否则返回(FFalsePassword)的长度
WM_GETTEXTLENGTH: if FAllowPasswordRead then inherited
else
if PChar(FFalsePassword) = nil then Result := 0
else Result := StrLen(PChar(FFalsePassword)); //如果允许读文本 才可以继续否则返回0或位密码
else
inherited;
end
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
PasswordEdit1 := TPasswordEdit.Create(self);
PasswordEdit1.parent := form1;
PasswordEdit1.Width := 150;
PassWordEdit1.Height := 21;
PasswordEdit1.Top := 115;
PasswordEdit1.Left := 80;
PasswordEdit1.PasswordChar := '*';
PasswordEdit1.AllowPasswordRead := false;
PasswordEdit1.Visible := true;
PasswordEdit1.Text:='Hello';
PasswordEdit1.FalsePassword:= '想读我?没门!'
end;
end.
相关文章推荐
- 实验 10 指针2 (2)为了防止信息被别人轻易窃取,需要把电码明文通过加密方式变换成为密文。变换规则是:小写字母z变换成为a,其它字符变换成为该字符ASCII码顺序后1位的字符,比如o变换为p。
- (爱加密系列教程十三) 如何防止工具(八门神器)进行内存修改
- 实验十(二)2、为了防止信息被别人轻易窃取,需要把电码明文通过加密方式变换成为密文
- 如何有效防止“蹭网”——简述Wi-Fi加密方式与破解
- Unity3D加密外壳如何做到防止反编译?
- 如何防止字符乱码:CharacterEncodingFilter的使用
- js中对arry数组的各种操作小结 瀑布流AJAX无刷新加载数据列表--当页面滚动到Id时再继续加载数据 web前端url传递值 js加密解密 HTML中让表单input等文本框为只读不可编辑的方法 js监听用户的键盘敲击事件,兼容各大主流浏览器 HTML特殊字符
- 如何控制文本框中只可以输入字符,禁止输入汉字?
- 如何加密Url防止被黑
- 加密芯片和芯片解密那些事:如何防止电子产品抄袭
- 如何防止博客园文章被窃取
- 如何防止字符乱码:CharacterEncodingFilter的使用
- 如何防止博客文章被窃取
- 如何使用jquery对特殊字符进行转义,防止js注入
- 如何用javascript计算文本框还能输入多少个字符
- 如何防止博客园文章被窃取
- vb 如何在Text文本框或Label里显示一个字符后自动换行
- 如何将文件通过base64字符加密以及解码保存到目标文件
- 如何用javascript计算文本框还能输入多少个字符
- 如何防止博客园文章被窃取