【摘要】身份認證作為網(wǎng)絡(luò)應(yīng)用系統(tǒng)的第一道防線,是最重要的安全服務(wù)。在高校信息化過程中,如何保障高校信息資源的安全性,已經(jīng)受到越來越多的關(guān)注。文章基于S/Key一次性口令身份認證系統(tǒng)以及Java套接字,Applet等技術(shù),詳細介紹了如何用Java套接字實現(xiàn)高校信息化系統(tǒng)中動態(tài)口令身份認證的過程,并相應(yīng)的給出了一些關(guān)鍵代碼。
【關(guān)鍵詞】身份認證,S/Key系統(tǒng),一次性口令,高校信息化
【中圖分類號】G40-057 【文獻標(biāo)識碼】B 【論文編號】1009—8097(2010)01—0120—04
一 引言
1 應(yīng)用背景
在目前的高校信息化系統(tǒng)中,統(tǒng)一身份認證是很重要的。而如何解決好身份認證是高校信息化系統(tǒng)中一個關(guān)鍵的問題。身份認證主要用于阻止非授權(quán)用戶對系統(tǒng)的入侵或訪問,是信息安全系統(tǒng)的基礎(chǔ)。根據(jù)所采用手段的不同,可分為基于秘密信息的和基于物理安全性的身份認證兩種?;诿孛苄畔⒌纳矸菡J證用的是靜態(tài)口令。每個合法用戶擁有一個用戶名,口令對,用戶登錄系統(tǒng)或使用某項功能時,需輸入自己的用戶名與口令,系統(tǒng)即可確認是否為合法。靜態(tài)口令身份認證方便,簡潔,但存在諸多缺點。動態(tài)口令身份認證是現(xiàn)在研究較多并且技術(shù)相對比較成熟的認證方式,它克服了靜態(tài)口令技術(shù)所固有的許多缺點,特別是對于分布式身份認證來說具有非常高的安全性。
2 靜態(tài)口令認證的缺點
(1)每次訪問系統(tǒng)時都要輸入靜態(tài)口令,易被偷窺泄密。
(2)靜態(tài)口令只能進行系統(tǒng)對用戶的單向認證,攻擊者可偽裝成系統(tǒng)騙取用戶口令。
(3)其安全性基于用戶設(shè)置的口令,很多用戶為了方便,設(shè)定的口令中含個人信息,如姓名、生日等,極易破譯 。且長期使用同一口令.被破解的可能性極大。
(4)在訪問不同安全級別的系統(tǒng)時,都要求用戶提供口令。用戶為方便記憶.往往采用相同的口令,而低安全級別的口令很容易被攻擊者獲得并用來對高安全級別系統(tǒng)進行攻擊。
(5)系統(tǒng)中用戶的口令以文件形式存儲在認證方,攻擊者可利用系統(tǒng)存在的漏洞獲取口令文件。一旦該文件被攻擊者得到,他們就可使用解密程序來破譯,從而獲取對系統(tǒng)的訪問權(quán)。
(6)口令在傳輸過程中可能被截獲。用戶連接其在遠程主機上的帳戶時,由于網(wǎng)上傳輸?shù)目诹顩]有加密,攻擊者可通過各種手段獲取用戶口令。如被截獲的是管理員的口令,那么獲取特權(quán)級訪問就變得很容易,已有許多系統(tǒng)被這種方法侵入。
顯然,作為目前身份認證最常用手段的靜態(tài)口令,不能很好的保證其安全性,需要一種經(jīng)常變化、不易推測、一次性使用的動態(tài)口令來實現(xiàn)安全可靠的身份認證,阻止未經(jīng)授權(quán)的非法訪問等。
3 動態(tài)口令的提出
在80年代初,美國科學(xué)家Leslie Lamport首次提出了利用散列函數(shù)產(chǎn)生一次性口令的思想,即用戶每次同服務(wù)器進行身份認證時,在網(wǎng)上傳輸?shù)恼J證口令都是加密后的密文形式,并且在每次認證時這些密文形式的認證口令都是不同的,也就是說密文口令是一次有效的。
這種一次有效的“動態(tài)口令”彼此之間無相關(guān)性,無法預(yù)測,跟蹤,截取,破譯。這樣,無論網(wǎng)上交易,轉(zhuǎn)賬,還是訪問內(nèi)部網(wǎng)絡(luò)等都能對訪問者身份進行準(zhǔn)確的認證,保證其唯一,合法。
本文首先介紹了一種經(jīng)典的動態(tài)口令身份認證系統(tǒng)——S/Key系統(tǒng),然后介紹了Java Socket的一些基本知識,最后重點介紹了如何用Java Socket實現(xiàn)動態(tài)口令身份認證,并給出了相應(yīng)的代碼。
為方便描述,約定符號如下:IDc為用戶C的身份標(biāo)識,A表示認證服務(wù)器,W為用戶秘密通行短語,N為初始序列號,S表示種子值,Pi表示用戶第i次登錄的一次性口令,H(x)表示單向哈希函數(shù),Hi(x)表示對x連續(xù)進行i次哈希運算, Ek(m)表示用密鑰k對信息m進行加密運算,Dk(m)表示用密鑰k對信息Ek(m)進行解密運算,即m=Dk(Ek(m))。
二 S/Key系統(tǒng)[1,2,3]
S/Key系統(tǒng)是一種一次一密認證系統(tǒng),客戶端和服務(wù)器端沒有保留口令及生成口令的全部信息,整個通信過程都是安全的,用戶每一次登錄系統(tǒng)所用的口令都是不同的,攻擊者通過竊聽得到的口令無法用于下一次認證,而且用戶秘密通行短語從不在網(wǎng)上進行傳輸,保證了在網(wǎng)絡(luò)上傳送的密碼只使用一次,可以有效防止通過竊聽進行重放攻擊,具有較高的安全性。
1注冊階段
用戶選擇自己的秘密通行短語W,服務(wù)器為每個用戶生成一個種子值S,用戶設(shè)置一次性口令序列的最大元素個數(shù)N,用戶輸入的S和N通過安全通道提交給認證服務(wù)器,認證服務(wù)器計算出一次性口令為P0=Hn(W+S)
第i次登錄的一次性口令:Pi=Hn-i(W+S)
數(shù)據(jù)庫中用戶C的注冊數(shù)據(jù)內(nèi)容為:用戶IDc,種子值S,初始序列號N,一次性口令P0
2 認證階段
第i次認證過程如下:
Step1 C→A:IDc;認證請求;
Step2 A→C:N-i,S;發(fā)送挑戰(zhàn);
Step3 C→A:Pi=Hn-i(W+S);計算一次性口令Pi并作為應(yīng)答;
Step4:服務(wù)器對收到的Pi再做一次哈希運算H(Pi),并將結(jié)果H(Pi)與保存在認證服務(wù)器端的該用戶上次成功登錄的一次性口令Pi-1比較,相同則通過認證,將N-i-1和Pi 寫入數(shù)據(jù)庫作為新的序列號和動態(tài)口令。
三 Java Socket,Applet[4]
網(wǎng)絡(luò)應(yīng)用程序的核心由一對程序組成------一個客戶程序和一個服務(wù)器程序,當(dāng)這兩個程序執(zhí)行的時候,創(chuàng)建一個客戶端進程和一個服務(wù)器進程,并且這兩個進程通過對套接字(socket)的讀寫來互相通信。Socket可以看成在兩個程序進行通訊連接中的一個端點,一個程序?qū)⒁欢涡畔懭隨ocket中,該Socket將這段信息發(fā)送給另外一個Socket中,使這段信息能傳送到其他程序中。
Java提供了一個豐富的、支持網(wǎng)絡(luò)的類庫,這些類使得應(yīng)用程序能方便地訪問網(wǎng)絡(luò)資源。Java提供了兩種通訊工具。它們是:使用用戶報文協(xié)議(UDP)的報文和使用傳輸控制協(xié)議/因特網(wǎng)協(xié)議(TCP/IP)的Sockets(套接字)。
Sockets套接字用TCP來進行通訊。套接字模型同其他模型相比,優(yōu)越性在于其不受客戶請求來自何處的影響。只要客戶機遵循TCP/IP協(xié)議,服務(wù)器就會對它的請求提供服務(wù)。這意味著客戶機可以是任何類型的計算機??蛻魴C不再局限為UNIX、Windows、DOS或Macintosh平臺,因此,網(wǎng)上所有遵循TCP/IP協(xié)議的計算機可以通過套接字互相通訊。
Applet可以翻譯為小應(yīng)用程序,可通過因特網(wǎng)下載并在接收計算機上運行的一小段程序,Java Applet就是用Java語言編寫的這樣的一些小應(yīng)用程序,它們可以直接嵌入到網(wǎng)頁中,并能夠產(chǎn)生特殊的效果,可以在B/S架構(gòu)中實現(xiàn)簡單的客戶端運算功能。
用Java編寫的應(yīng)用程序簡潔,代碼少,對于新手來說它的可讀性強。Java與平臺無關(guān),為了對出現(xiàn)在I/O和網(wǎng)絡(luò)操作中的一般問題進行健全的解決,它提供了例外機制,并且它的線程工具提供了一種能夠簡單的實現(xiàn)強大服務(wù)器的方法。由于Java有著豐富的支持網(wǎng)絡(luò)的類庫,用Java進行客戶服務(wù)器編程變得越來越流行,并且甚至可能變成未來幾年中的規(guī)范。
基于以上原因,本人選擇Java Socket實現(xiàn)動態(tài)口令身份認證的雙方數(shù)據(jù)通信,采用流行的B/S架構(gòu),客戶端采用Java Applet實現(xiàn)當(dāng)前動態(tài)口令的計算,服務(wù)器端采用多線程技術(shù)以便支持大量用戶的訪問。
四 具體實現(xiàn)[5][6][7]
由于S/Key系統(tǒng)不能抵抗小數(shù)攻擊,且在step2存在挑戰(zhàn)信息N-i,S 傳輸過程中可能有被非法竊聽而泄漏的危險性,故本人參考眾多動態(tài)口令算法對S/Key系統(tǒng)作了初步的改進,加入了對服務(wù)器端的雙向認證和對挑戰(zhàn)信息的加密。
改進后的第i次認證過程如下:
Step1 C→A:IDc;認證請求;
Step2 A→C:E K (N-i,S,Pi-1);發(fā)送挑戰(zhàn),K=H(W);
Step3 C→A:DK (N-i,S,Pi-1),Pi=Hn-i-1(W+S);客戶端生成K=H(W),解密獲得N-i,S,Pi-1 并計算一次性口令Pi先判斷如果H(Pi)= Pi-1 則對服務(wù)器認證通過,將Pi 發(fā)送給服務(wù)器作為應(yīng)答;
Step4:服務(wù)器對收到的Pi再做一次哈希運算H(Pi),并將結(jié)果H(Pi )與保存在認證服務(wù)器端的該用戶上次成功登錄的一次性口令Pi-1比較,相同則通過認證,并更新數(shù)據(jù)庫,將N-i-1和Pi 寫入數(shù)據(jù)庫作為新的序列號和動態(tài)口令。
1數(shù)據(jù)庫設(shè)計
說明:在我們的數(shù)據(jù)庫中,S 是認證服務(wù)器隨機產(chǎn)生的大于1000的種子值,N-i為用戶第i次接受認證時的序列號,初始值為用戶注冊時輸入的序列號N,Pi =Hn-i(W+S)為用戶第i次接受認證時的認證口令,初始值為P0=Hn(W+S)
為了保證step2發(fā)送挑戰(zhàn)N-i,S 傳輸過程中的數(shù)據(jù)安全性,我們在數(shù)據(jù)庫中加入一項秘密通行短語的散列值H(W)作為密碼加密挑戰(zhàn)信息,由于散列函數(shù)的不可逆性,不會引起秘密通行短語的泄漏。加密算法我們選用DES。
2 注冊階段
該階段通過兩個文件來實現(xiàn)
registerform.html:實現(xiàn)注冊信息的表單輸入
關(guān)鍵代碼:
long seed=(long)(Math.random()*1000)+1000;//隨機函數(shù)生成種子值
String initpasswd =MD5bean.getMD5ofStr(W+S);
for(inti=1;i initpasswd=MD5bean.getMD5ofStr(initpasswd); //計算P0= (W+S)表示對單向函數(shù)H(W+S)進行n次運算 3 認證階段[8] 該階段主要由一個applet,一個servlet,兩個java bean 文件組成 (1)客戶端程序 newloginApplet.java是唯一的需要在客戶端執(zhí)行的文件,用于在客戶端向用戶顯示登陸界面,接受客戶的信息輸入,產(chǎn)生動態(tài)口令,發(fā)送給服務(wù)器,接受服務(wù)器對客戶的身份驗證。 該文件有一個繼承Applet類的 newloginApplet類。 NewloginApplet類圖如下: 函數(shù)邏輯處理調(diào)用關(guān)系圖如圖3: 函數(shù)功能說明: Init()初始化applet顯示登陸界面 handleEvent()處理登陸信息并建立連接 validateName()驗證該用戶是否已經(jīng)注冊 validateDPswd()驗證用戶口令是否正確,該口令為不斷變化的動態(tài)口令DynamicPassword。 (2) 服務(wù)器端程序 服務(wù)器端程序包含三個文件: loginServlet.java是一個繼承HttpServlet類的servlet文件,用于向客戶端送出applet,并啟動認證服務(wù)器監(jiān)聽連接。 MyServer.java被loginServlet啟動后建立一個服務(wù)器端socket監(jiān)聽連接,獲得一個連接后交由serverLogic處理,MyServer重新進入監(jiān)聽狀態(tài)。 ServerLogic.java處理獲得的連接請求,即處理客戶端的認證請求,如果認證成功,則返回登陸成功頁面,否則返回錯誤提示。 采用面向?qū)ο蟮姆治鲈O(shè)計方法對認證邏輯進行分析設(shè)計,獲得描述業(yè)務(wù)邏輯的類圖如下: 說明:Login函數(shù)用于判斷如果用戶未登陸,則向客戶端送出用于登陸的applet 五 身份認證程序?qū)崿F(xiàn)綜述[9] 1服務(wù)器端程序基本功能: (1)創(chuàng)建一個serverSocket對象,在指定端口監(jiān)聽客戶端發(fā)來的請求 (2)在接收到請求時,accept()方法將返回一個Socket對象 (3)用上述Socket對象創(chuàng)建輸入輸出流對象 (4)通過輸入輸出流與客戶交互 (5)交互完畢,關(guān)閉輸入輸出流與 Socket (6)服務(wù)器程序運行結(jié)束,關(guān)閉ServerSocket 服務(wù)器端類功能說明: (1)啟動服務(wù)器程序的Serverlet-- LoginServlet.class Servlet程序---LoginServlet負責(zé)啟動服務(wù)器程序。在它的init()方法中啟動了一個類型為MyServer的對象實類,該實類作為一個后臺線程在TCP端口4000監(jiān)聽客戶的請求. (2)服務(wù)器類MySserver.class MyServer類是一個線程,它首先根據(jù)指定的端口創(chuàng)建一個ServerSocket對象,調(diào)用ServerSocket對象的accept()方法監(jiān)聽是否有客戶發(fā)出連接請求,如果有就創(chuàng)建一個類型為ServerLogic的對象,并將accept()方法返回的Socket對象傳給創(chuàng)建的ServerLogic對象以便將該連接的控制權(quán)交給此ServerLogic對象,然后此MyServer實類重新調(diào)用ServerSocket對象的accept()方法監(jiān)聽是否有客戶發(fā)出新的連接請求 (3)認證邏輯類ServerLogic.class ServerLogic對象以線程的方式進行工作,負責(zé)處理一個Socket連接。他負責(zé)接受客戶端的請求,進行處理,其處理過程為判斷客戶是否已經(jīng)注冊。首先,它從Socket中讀取Applet傳來的用戶名,并進行驗證,如果是正確的,則向Socket的輸出流中寫入“true”,然后在輸出流中寫入客戶的種子值,初始序列號,初始口令的加密值,等待客戶端發(fā)送動態(tài)口令進行下一步驗證。如果驗證沒有通過,就向輸出流中寫入“1”。 2 使用Socket的客戶端程序 (1)客戶端使用面向連接的通信方式與服務(wù)器通信 (2)創(chuàng)建Socket對象建立與服務(wù)器的連接 (3)用該Socket對象創(chuàng)建輸入輸出流 (4)與服務(wù)器交互: Applet程序——newLoginApplet首先接收用戶輸入的用戶名,然后調(diào)用validateuser()方法將用戶名數(shù)據(jù)送到服務(wù)器側(cè)進行驗證,如果通過,就接收服務(wù)器發(fā)來的種子值,初始序列號,初始口令,對其解密,并計算動態(tài)口令,發(fā)給服務(wù)器接受下一步認證。 (5)交互完畢,關(guān)閉輸入,輸出流與Socket 參考文獻 [1] N Haller.The S/KEY One-Time Password System[S].RFC 1760,1995. [2] N Haller.A One-Time Password System[S].RFC 2289,1998. [3] 王敏,戴宗坤,方勇.一種新的一次性口令機制及其應(yīng)用[J]. 計算機應(yīng)用研究,2005,(1):108-109 [4] 陳劍,周意青,劉振華.JavaApplet的安全性及應(yīng)用[J].計算機應(yīng)用研究,2001,(11):70. [5] 敖山,李新中,唐守廉.時間敏感的動態(tài)口令身份認證系統(tǒng)研究及設(shè)計[J].計算機應(yīng)用研究,2004,24(7):151. [6] 王濤,謝冬青,周洲儀.一種新的雙向認證的一次性口令系統(tǒng)TAOTP[J].計算機應(yīng)用研究,2005,(9):128-130. [7] 朱建新,楊小虎.基于指紋的網(wǎng)絡(luò)身份認證[J].計算機應(yīng)用研究.2001,(12):14-17. [8] 汪同慶,魯軍,華晉,倪水平.基于MD5 算法和Schnorr 協(xié)議的雙因素身份認證系統(tǒng)[J].計算機應(yīng)用研究.2004,(12):137-139. [9] James F.Kurose Keith w.Ross計算機網(wǎng)絡(luò)---自頂向下方法與Internet特色