繆 蕊 ,鐘志賢 ,劉 珺 ,包愛民 ,姜 維,申小琦
(1.昆明冶金高等專科學(xué)校網(wǎng)絡(luò)管理與信息化部,云南 昆明 650033; 2.吉林省明日科技有限公司,吉林 長春 130000)
隨著國家大力開展數(shù)字化經(jīng)濟,虛擬賬號的數(shù)量呈指數(shù)上升,隨之而來的就是與日俱增的數(shù)據(jù)安全問題。因為互聯(lián)網(wǎng)有著極強的匿名性,所以服務(wù)商很難分辨當(dāng)前進行遠(yuǎn)程操作的是客戶本人還是冒名頂替的不法分子。為了保證電子商務(wù)交易安全和電子支付安全,服務(wù)商推出了多種身份驗證方式。其中最常使用的是靜態(tài)密碼驗證,用戶通過輸入用戶名與密碼進行身份認(rèn)證,密碼是靜態(tài)的,可重復(fù)使用。但使用靜態(tài)密碼進行認(rèn)證存在巨大風(fēng)險,服務(wù)商為了維護這些密碼以獲得更高的安全性,需要耗費大量的人力、物力。用戶會為了方便管理而使用弱密碼或低強度密碼(例如自己的電話號碼、生日、樓棟號等)。這樣的靜態(tài)密碼極易被盜用或破解。密碼被盜用后,非法用戶即可登錄應(yīng)用平臺對用戶數(shù)據(jù)進行肆意篡改,從而造成財產(chǎn)損失。
隨著網(wǎng)絡(luò)應(yīng)用的復(fù)雜化、攻擊手段的多樣化,靜態(tài)密碼驗證的安全缺陷也越來越明顯,已經(jīng)不再適用于安全性要求較高的網(wǎng)絡(luò)應(yīng)用系統(tǒng)。為了解決靜態(tài)密碼存在的缺陷,一次性動態(tài)口令的認(rèn)證方式應(yīng)運而生。但是,目前現(xiàn)有的一次性口令認(rèn)證方案也并不十分完善,有的需要安裝第三方插件,有的平臺兼容性與可移植性較差,各種方案在執(zhí)行性能和安全性能上還存在一定缺陷。設(shè)計更加完善的一次性口令認(rèn)證方案,可以為更多的網(wǎng)絡(luò)系統(tǒng)提供更加安全可靠的身份認(rèn)證,保障用戶在使用平臺時的安全性、私密性。
本文將介紹基于Java語言的一次性動態(tài)口令算法,采用更加完善的認(rèn)證,增強認(rèn)證口令的隨機性,做到真正的一次一密,并更加容易地部署到網(wǎng)絡(luò)應(yīng)用系統(tǒng)中。
在網(wǎng)絡(luò)安全開展的早期,為了防止他人盜取數(shù)據(jù),服務(wù)商提供“2套密碼”服務(wù):登錄用一個密碼,辦理業(yè)務(wù)用另外一個密碼。但很快這種方案也出現(xiàn)漏洞,不法分子只需同時捕捉到2套密碼就可以非法竊取網(wǎng)絡(luò)數(shù)據(jù)。之后服務(wù)商又推出了非常多的加密方案,銀行作為金融機構(gòu),對于網(wǎng)絡(luò)操作都十分敏感,所以銀行對于身份驗證的要求最為嚴(yán)格。
隨著網(wǎng)絡(luò)銀行的業(yè)務(wù)開展,銀行為了保證用戶資金的安全性,要求用戶在進行網(wǎng)絡(luò)支付時,除了驗證登錄密碼外,還要完成另一套驗證操作。最早銀行推出了口令卡業(yè)務(wù),用戶需到銀行申請一個可刮擦、數(shù)字隨機的二維矩陣卡,如圖1所示。用戶每次進行網(wǎng)絡(luò)支付時,銀行都會要求輸入口令卡中指定行、列的數(shù)字,由此來驗證用戶真實身份。雖然口令卡用起來非常方便,但也存在著被盜取的安全隱患,并且口令卡上的密碼數(shù)量有限,一旦用戶刮完所有數(shù)字,就需要重新申請。
圖1 工商銀行口令卡Fig.1 ICBC password card
為了提高賬戶安全性,銀行推出了網(wǎng)銀盾業(yè)務(wù),俗稱U盾,如圖2所示。這是一個寫有固定加密程序的U盤,具有不可復(fù)制性,所以安全性極高。但U盾也存在一個缺陷,就是必須在已安裝銀行驅(qū)動程序的計算機上操作,對使用場景的要求極高。
所以U盾已成為網(wǎng)銀加密的主要產(chǎn)品,但為了簡化用戶的操作過程,銀行又推出了一次性動態(tài)口令令牌產(chǎn)品。這是一款小巧的自帶電池、液晶屏的數(shù)碼產(chǎn)品,通常液晶屏中會隨機顯示6個數(shù)字,這6個數(shù)字就是一次性動態(tài)口令,如圖3所示。動態(tài)口令雖然是隨機數(shù)字,但卻和銀行的服務(wù)器保持了一致性,用戶在任意一臺計算機上進行網(wǎng)絡(luò)支付時,只需輸入當(dāng)前令牌顯示的一次性口令就可以完成支付操作,這樣就解除了使用場景的限制。
圖2 建設(shè)銀行一代網(wǎng)銀U盾 圖3 中國銀行的動態(tài)口令令牌Fig.2 CCB generation I E-bank USBkey Fig.3 BOC dynamic password token
圖4 QQ安全中心界面示意圖Fig.4 QQ security center interface diagram
隨著智能手機的普及,很多開發(fā)商將動態(tài)口令令牌由硬件產(chǎn)品轉(zhuǎn)移到了智能手機軟件上,這樣極大地降低了推廣成本。很多銀行也將口令令牌功能轉(zhuǎn)移到手機軟件上,用戶直接安裝官方軟件即可激活,無需再到柜臺申請。除了銀行以外,各大互聯(lián)網(wǎng)公司也推出了各自的動態(tài)口令軟件,例如圖4所示的騰訊QQ安全中心軟件。
一次性口令也叫一次性密碼(One Time Password,OTP)。OTP 的計算公式為:OTP(K,C) = Truncate[HMAC-SHA-1(K,C)],其中,K表示明文;C是加密算法對明文進行簽名的秘鑰;HMAC-SHA-1是從 SHA1 哈希函數(shù)構(gòu)造的一種鍵控哈希算法加密算法,可以根據(jù)任意字符串生成一個160 位的哈希值;Truncate 是截取加密結(jié)果的方法。一次性口令的特點是用戶可以根據(jù)服務(wù)商提供的動態(tài)口令程序生成的數(shù)字來輸入動態(tài)口令,而且每個登錄服務(wù)器的口令均只能使用一次,這樣可使竊聽者或黑客無法通過竊聽和破解口令來偽造登錄。同時利用單向散列函數(shù)的不可逆性,防止密碼被竊聽或破解后進行二次登錄。
HOTP 的全稱是HMAC-based One-Time Password,表示根據(jù)某一特定的事件及相同的種子值作為參數(shù),通過哈希算法運算出一致的密碼。
HOTP的計算公式為HOTP(K,C) = Truncate[HMAC-SHA-1(K,C)],其中,C是一個與事件同步的隨機值,在HOTP的基礎(chǔ)之上,將當(dāng)前時間作為參數(shù)C,就發(fā)展出了TOTP算法。
TOTP的全稱是Time-based One-time Password ,原理同HOTP一致,只是將其中的參數(shù)C變成了時間,計算公式為:TOTP(K,C) = Truncate[HMAC-SHA-1(K,C)]。
在Java語言中,時間戳可以采用System.currentTimeMillis()方法返回的當(dāng)前時間毫秒數(shù),這是一個long類型整數(shù),每一次調(diào)用都會基于時間的不同而得到不同的數(shù)值。
公式中的K參數(shù)可以采用“用戶唯一標(biāo)志 + token”的方式拼接。用戶的唯一標(biāo)志可以是用戶的身份證號、電話號、郵箱等,也可以是服務(wù)端提供用戶的認(rèn)證證書,例如電子證書號碼、用戶ID等。明文在加密之前要在末尾拼接token參數(shù),這樣可以極大地增加破譯難度。token即鹽值,其本身是一個無序、無語義的字符串,服務(wù)端和客戶端每隔一段時間就更換并同步token參數(shù),這樣可以極大提高一次性口令的安全性。
獲得6位一次性動態(tài)口令需要進行以下計算過程:
1)將K參數(shù)和C參數(shù)進行HmacSHA1加密,得到加密后的字節(jié)數(shù)組;
2)取出字節(jié)碼數(shù)組的后4個字節(jié);
3)為了加大加密算法的復(fù)雜度,翻轉(zhuǎn)取出的4個字節(jié)的順序;
4)按照翻轉(zhuǎn)之后的順序,將4個字節(jié)拼接成1個32位的整數(shù);
5)截取此32位整數(shù)的最后6位數(shù)字,這6位數(shù)字就是算法生成的一次性動態(tài)口令。其計算過程如圖5所示。
圖5 計算動態(tài)口令的過程Fig.5 Dynamic password calculation process
使用Java代碼開發(fā)一次性動態(tài)口令算法,首先要實現(xiàn)HmacSHA1加密算法。JDK的javax.crypto包已提供了該算法的API。用Java編寫的程序不但簡潔、代碼少,而且可讀性較強。Java與平臺無關(guān),可移植性強,并自帶豐富的網(wǎng)絡(luò)類庫,功能強大。基于以上原因,項目中選擇采用Java來實現(xiàn)動態(tài)口令身份認(rèn)證。
本方案應(yīng)用于學(xué)校智慧教室控制系統(tǒng)的教師身份認(rèn)證,通過認(rèn)證后,教師登錄移動智能終端,并獲得智慧教室設(shè)備的控制權(quán)限。
為方便教師使用,設(shè)計遵循以下原則:1)不需要在智慧教室控制端安裝其它第三方組件,直接嵌入算法即可;2)可移植性高,兼容多種移動端設(shè)備;3)提供雙向認(rèn)證。
圖6 基于時間同步身份認(rèn)證原理圖Fig.6 Identity authentication diagram based on the time synchronization
基于以上原則,本方案選擇采用基于時間同步的身份認(rèn)證。該技術(shù)的核心算法是單項散列函數(shù),函數(shù)的輸入?yún)?shù)是由“證書+鹽值”拼接出的加密明文和當(dāng)前時間的毫秒數(shù)(客戶端和服務(wù)器需要校準(zhǔn)為統(tǒng)一的時間),輸出參數(shù)是長度固定的散列值。該散列值就可以作為用戶身份的安全憑證。原理如圖6所示。
該技術(shù)的核心算法是encrypt()方法,該方法的2個參數(shù)分別為由“證書+鹽值”拼接出的加密明文和當(dāng)前時間的毫秒數(shù)(客戶端和服務(wù)器需要校準(zhǔn)為統(tǒng)一的時間),返回值為經(jīng)過HmacSHA1算法加密后得到的1個32位整數(shù)(可能是負(fù)數(shù))。HmacSHA1是從SHA1哈希函數(shù)構(gòu)造的一種鍵控哈希算法,很難找到逆向規(guī)律,所以加密安全性極高。前、后端在同一時間計算出的口令具有一致性,可以根據(jù)此口令作為用戶的身份認(rèn)證標(biāo)志,前、后端的計算過程如圖7所示。
圖7 使用動態(tài)口令進行身份認(rèn)證順序Fig.7 Sequence diagram using the dynamic password for identity authentication
核心代碼如下:
private static int encrypt(String encryptText, String encryptKey) {
try {
byte[] data = encryptKey.getBytes("UTF-8");
// 根據(jù)給定的字節(jié)數(shù)組構(gòu)造一個密鑰,第二參數(shù)指定一個密鑰算法的名稱
SecretKeysecretKey = new SecretKeySpec(data, "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(secretKey);// 密鑰初始化
// 完成加密
byte ciphertext[] = mac.doFinal(encryptText.getBytes("UTF-8"));
int num = 0;// 待拼接數(shù)字
for (int i = 0; i< 4; i++) {// 取4個字節(jié)
// 將數(shù)組后4個字節(jié)順序翻轉(zhuǎn)并拼接成一個32位數(shù)字
num += ciphertext[ciphertext.length - 1 - i] << 8 * (3 - i);
}
return num;
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return -1;
}
編寫Test測試類,設(shè)定一個證書和一個token,獲取當(dāng)前毫秒數(shù),將更新時間設(shè)定為 3 s,將拼接好的明文和時間進行加密,每隔 1 s 輸出一次口令,查看運行結(jié)果,完整代碼如下:
public class Test {
public static void main(String[] args) {
String certificate = "8898763578363844";// 證書或公鑰
String token = "UWzwth6I";// 加密參數(shù)
String key = certificate + token;// 拼接加密內(nèi)容
new Thread() {
public void run() {
while (true) {
try {
// 當(dāng)前時間毫秒數(shù)
long time = System.currentTimeMillis();
// 打印隨機口令,3 s更新
System.out.println(JTOTP.getPassword(key, time, 3));
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}.start();
}
}
運行結(jié)果如下:
352081
352081
012760
012760
012760
192007
192007
192007
854810
854810
854810
經(jīng)測試,即使代碼在兩臺計算機上運行,只要計算機本地時間一致,就會得到同步的結(jié)果。如果修改了用戶證書或token,動態(tài)口令就會立即改變。
本套代碼可以直接用于基于Java語言開發(fā)的Android系統(tǒng)程序,在用戶證書、token和本地時間一致的條件下,移動端得到的動態(tài)口令與服務(wù)器一致,運行速率快,可移植性高,能夠滿足智慧教室控制系統(tǒng)對教師身份認(rèn)證的要求。