讓密碼更安全

---- 隨着應用軟件的日益豐富,需要使用密碼的地方也越來越多,尤其是對於上網的人來說,密碼幾乎無處不在。然而在當前各種應用軟件中普遍存在密碼的安全問題,其原因在於各種開發工具中編輯框存在安全漏洞。密碼輸入顯示是需要保密的,所以用來做輸入和顯示的編輯框可以設置passwordchar,這時候編輯框就會只顯示‘*’之類的字符,而將真正的文本隱藏起來。這樣似乎文本就無法看到了,然而事實上這樣的保護是非常脆弱的,有很多辦法可以突破這層保護,最簡單的辦法就是使用SendMessage向編輯框傳送一個EM_SETPASSWRODCHAR消息,將Passwordchar設置爲0,就可以讓密碼原形畢露,而且windows並沒有對設置了passwordchar的編輯框文本讀取進行保護,所以也可以編程直接讀出密碼文本。實際上現在已經有了不少這樣的軟件,還記得Revelation嗎,一個15k的小程序卻使得微軟不得不出面解釋,所以對於重要的密碼還是再來加上一層保護吧。

---- 由於各種開發工具實際上都在使用Windows系統編輯框,所以從VC、VB到BC、Delphi等無一倖免,如何在自己的程序中避免這種情況呢,一個簡單的辦法就是子類化(subclassing),也就是使用自定義的編輯框WindowProc來進行消息處理,對於passwordchar的設置和文本讀取消息(分別是WM_GETTEXT 和EM_SETPASSWORDCHAR))進行檢查,把那些非法操作過濾掉。對於VC來說是非常簡單的,可以從CEdit直接派生一個安全的新類CPwdEdit:首先用ClassWizard生成新類,然後加入共有變量BOOL m_bLock,並重載WndProc(),修改下面兩個成員函數:


CPwdEdit::CPwdEdit()
{
  m_bLock=FALSE;
}
LRESULT CPwdEdit::WindowProc(UINT message,
WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here
and/or call the base class
//在這裏加入消息檢查
  if( m_bLock && (message==WM_GETTEXT ||
message==EM_SETPASSWORDCHAR) )
    return 0;
---- //對於EM_SETPASSWORDCHAR,wParam是緩衝區大小,lParam是緩衝區地址,所以在這裏可以向緩衝區拷貝一個設定的字符串來迷惑讀取程序。 //其他消息調用缺省窗口函數

  return CEdit::WindowProc(message, wParam, lParam);
}

---- 使用時,只需要設置m_bLock=TRUE就可以阻止revelation的讀取了。假定在對話框MyDlg中有一個編輯框IDC_EIDT1,用法如下:

CPwdEdit m_edit1;
BOOL CMyDlg::OnInitDialog()
{
。。。
// TODO: Add extra initialization here
m_edit1.SubclassDlgItem( IDC_EDIT1,this );
  m_edit1.SetPasswordChar( '*' );
  m_edit1.SetWindowText( "12345" );
  m_edit1.m_bLock=TRUE;
。。。
}

---- 直接使用SDK就稍微複雜一些,需要手工進行子類化,設定一個對話框應用,加入如下代碼:


HWND hwndEdit;
BOOL bLock=FALSE;
#ifdef STRICT
 WNDPROC OldEditProc;
#else
 FARPROC OldEditProc;
#endif

//自定義窗口函數
LRESULT CALLBACK MyEidtProc
( HWND hwnd,UINT
uMsg,WPARAM wParam,LPARAM lParam )
{
  LRESULT lResult=0;
if( bLock && (uMsg==WM_GETTEXT ||
uMsg==EM_SETPASSWORDCHAR) )
return lResult;
//下面調用原窗口函數
  if( (DWORD)OldEditProc!=(DWORD)MyEidtProc )
lResult=CallWindowProc(OldEditProc,
hwnd,uMsg,wParam,lParam);
return lResult;
}
//在對話框中進行子類化
BOOL WINAPI DlgProc (HWND hwnd, UINT uMsg,
WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
//在初始化代碼中進行子類化
    case WM_INITDIALOG:
//得到編輯框句柄
hwndEdit=GetDlgItem( hwnd,
IDC_ EDIT1 );
//得到原窗口函數地址
OldEditProc = GetWindowLong(
hwndEdit,GWL_WNDPROC );
//設置自定義窗口函數
SetWindowLong( hwndEdit,
     GWL_WNDPROC,
(DWORD)MyEidtProc );
bLock=TRUE;
break;
。。。
}
}
---- 經過測試,以上的方法可以成功地阻止Relevation1.1和其他軟件竊取密碼,不過由於這個漏洞實際上出自Windows系統本身,所以在編寫軟件時還是要注意這個問題,儘量避免密碼的直接顯示。

 

摘自:http://www.xici.net/main.asp?url=/u17083/d31454.htm

發佈了26 篇原創文章 · 獲贊 13 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章