摘 要:在現代工作與生活中,人們越來越離不開網絡,網絡安全已經成為最熱門的話題。OpenSSH就是在這種環(huán)境下產生的。在基于OpenSSH技術的通信過程中會對傳輸文件包括口令在內進行加密,這樣就極大的增強了傳輸過程的安全性。因此,OpenSSH被越來越多的應用在系統(tǒng)中以保證數據的安全傳輸。本文提供了一種基于OpenSSH實現用戶系統(tǒng)與控制中心間文件安全傳輸的解決方案。
關鍵詞:OpenSSH;認證;安全傳輸;加密
中圖分類號:TP393.08
OpenSSH是SSH中的一種,是一種完全免費并公開源代碼的安全解決方案。OpenSSH的英文全稱是Open Secure Shell,作為一種網絡安全的解決方案,它提供了服務端后臺程序和客戶端工具,對遠程控件及文件傳輸過程中的數據進行加密。
OpenSSH最主要的兩個功能是:
(1)提供安全的遠程登錄。相比于以明文發(fā)送用戶名和口令的telnet和rlogin遠程登錄服務,OpenSSH是以密文的方式發(fā)送用戶名和口令進行遠程登錄。顯然,OpenSSH要比telnet和rlogin更安全。SSH的命令格式為:ssh user@host。其中,user為遠程機器的用戶名,host為遠程機器的主機名。
(2)提供安全的文件傳輸。相對于傳統(tǒng)的ftp、rcp、E_mail等文件傳輸程序,SSH提供了一種更為安全的解決方案。其中,E-mail雖然對郵件進行了base64編碼,但只需在網上下載一小段解碼程序(或自己編寫一個簡單的解碼程序)就能對其進行解碼,使整個郵件到達接收端時再自動解密,因而SSH能保證文件的安全傳輸。Scp的命令格式為:scp testfile user@host:testfile。其中,testfile為要傳輸的文件名,user為遠程機器的用戶名,host為遠程機器的主機名。
在使用SSH來增進系統(tǒng)的安全性,需要經過幾次的的認證進行連接,過程如下:
(1)協(xié)商雙方版本號。首先由客戶端先發(fā)起TCP連接請求,與服務器建立TCP連接之后進入等待狀態(tài)。接著服務器發(fā)送一個格式為“SSH-<主協(xié)議版本號>.<次協(xié)議版本號>-<軟件版本號>”的報文,標志自己的版本號??蛻舳私邮盏椒掌鞯陌姹咎栔髮ζ溥M行匹配。如果服務器的協(xié)議版本號低于自己的版本號但又能支持,則以服務器的低版本號作為自己的標志版本號報文回應給服務器;如果服務器的協(xié)議版本號高于或等于自己的版本號,則以客戶端實際的版本號回應服務器。
最后,服務器匹配客戶端回應的版本號,如果支持該版本,則協(xié)商完成,進入下一階段;如果不支持該本版,則斷開與客戶端的TCP連接。
(2)協(xié)商密鑰和算法。服務器和客戶端分別向對方發(fā)送算法協(xié)商報文,內容包含本端支持的公鑰算法列表、加密算法列表、MAC算法列表、壓縮算法列表等。服務器與客戶端收到各自發(fā)來的報文進行算法協(xié)商,最終確定雙方確定使用的算法。如果有任何一種算法協(xié)商失敗,服務器都將終止與客戶端的連接。最后,服務器與客戶端雙方根據DH交換算法和主機密鑰對等參數生成相同的會話密鑰和會話ID,同時也完成客戶端對服務器的身份確認。在之后的數據傳輸過程中,通信雙方都將使用這一會話密鑰進行數據的加密和解密處理,從而保證了數據的傳輸安全。需要說明的是,會話密鑰只對本次通信有效,下次通信必須重新生成新的會話密鑰[1]。
(3)認證階段。SSH提供三種的認證方法:公鑰認證、密碼認證和可信主機認證。其中公鑰認證的優(yōu)先級最高,可信主機認證的優(yōu)先級最低。在默認配置情況下,SSH是禁用可信主機認證的[2]。
通信雙方建立連接之后的認證步驟如下:
(1)客戶端通過發(fā)送一個包含自己用戶名的SSH_CMSG_USER包,向服務器提出認證請求。
(2)服務器接收到客戶端的SSH_CMSG_USER包之后,檢索本地用戶名列表來判定該用戶是否存在。如果用戶存在且不需要進一步認證,服務器返回一個認證成功信息SSH_SMSG_SUCCESS包給客戶端。如果用戶不存在或需要進一步認證,則返回一個認證錯誤信息SSH_SMSG_FAILURE包給客戶端,同時仍繼續(xù)保持接收狀態(tài)。因此,需要說明的一點是,客戶端是無法依據服務器返回的認證錯誤信息來判定自己的用戶名是否存在于服務器端。
(3)客戶端接收到服務器發(fā)來的SSH_SMSG_FAILURE包之后,不停向服務器提出申請嘗試新的認證方式。
(4)服務器根據認證信息接受客戶端的認證嘗試申請。在三種情況下服務器會停止嘗試:第一種,某一種認證方式通過了;第二種,認證次數達到上限;第三種,認證超時。對于第一種情況,服務器會返回SSH_SMSG_SUCCESS包,對于第二、三種情況,服務器會返回SSH_SMSG_FAILURE包,直至關閉連接。
(5)如果認證成功,客戶端則向服務器提交會話請求,并等待服務器的響應。服務器對會話請求進行分類處理,請求被接受則返回SSH_SMSG_SUCCESS包,請求被拒絕或無法識別則返回SSH_SMSG_FAILURE包。
具體認證過程如圖1所示:
圖1 SSH認證過程示意圖
設計思路:
實現文件傳輸并不是一件很難的事,但要保障傳輸的安全卻比較困難。實現安全文件傳輸的思路如下:
(1)基于OpenSSH的開源協(xié)議簇對通信加密來實現文件的安全傳輸。具體文件傳輸的實施方案可以采用直接調用ShellExcute()函數或創(chuàng)建一個子進程的方法來實現。顯然,采用直接調用的方法更簡單,但這種方法的不足之處在于其函數的返回值無法確定文件傳輸成功與否,這樣便降低了文件傳輸的可靠性。因此,本文采用創(chuàng)建子進程的方法來實現文件傳輸。
(2)文件傳輸通常都比較耗時,出于對傳輸效率的考慮,可以通過多線程協(xié)作方式,設計專門的輔助線程來完成文件傳輸工作,以此來提高傳輸效率。
具體實現:
(1)MFC AppWizard[exe]的應用程序。用MFC AppWizard[exe]生成一個基于對話框的應用程序。在MFC AppWizard-step1 of 4中選中Dialog based單選項,在MFC AppWizard-step2 of 4中,確保About box復選框不被選中,其它都接受默認選項。
(2)編輯對話框資源。編輯對話框資源,如圖2所示。
圖2 程序的主對話框
(3)撰寫線程參數對應的結構。本程序由主線程啟動輔助線程來處理文件傳輸,一般來說,主線程要傳遞一些信息給由它啟動的輔助線程,例如主線程的窗口句柄、一些字符信息等,本程序中要傳遞的信息用結構ThreadPara來存儲。
Typedef struct {HWND hWnd;
CString strPara;}ThreadPara;
(4)添加變量。本程序主要實現安全文件傳輸,因而用到的參數主要有:要傳輸的文件的全路徑名、目的用戶名等,具體如下:
Public:
//{{AFX_DATA(COpensshScpDlg)
CIPAddressCtrl m_IPAddrDesCtrl; //目的IP控件
CString m_strSource; //要傳輸的文件的全路徑名
CString m_strUser; //目的用戶名
//}}AFX_DATA
private:
CString m_strFileName; //要傳輸的文件名
CWinThread* m_pThread; //傳輸文件線程
(5)定義全局函數。包線程函數及其用到的輔助函數。
UINT MyThreadProc(LPVOID pPara); //定義線程函數
int WinExecuteProc(CString FileName,BOOL bVisible); //線程函數中用到的輔助函數
最后,撰寫“傳輸”的響應函數,通過啟動輔助線程來實現文件傳輸功能,從而最終實現基于OpenSSH的安全傳輸。
參考文獻:
[1]文自勇.基于OpenSSH實現Windows與Linux平臺間的安全文件傳輸[J].成都信息工程學院學報,2005.
[2]吳鐵軍.基于安全套接層的虛擬專用網服務器的開發(fā)[D].華中科技大學,2006.
[3]熊克琦.SSH協(xié)議的中間人攻擊研究[D].北京郵電大學,2008.
作者簡介:陳明(1984.01-),男,福清人,講師,本科。
作者單位:福建船政交通職業(yè)學院,福州 350007