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