曹鵬飛 李 杰 楊 君
(三江學院計算機科學與工程學院 江蘇 南京 210012)
現如今移動支付已成為人們日常生活中不可缺失的一部分,用戶使用智能手機就可以完成支付業務,技術主要有:藍牙支付技術、NFC支付技術、二維碼支付技術、人臉識別支付技術[1-2]。
隨著移動支付技術的發展,移動支付的安全問題隨之出現,眾多用戶使用靜態二維碼作為收款碼,但靜態條碼容易被偽造,誤導客戶掃描偽碼,實施欺詐,導致賬戶資金被盜刷、個人敏感信息泄露等風險問題。在移動支付交易過程中,移動終端與支付平臺之間的通信安全也至關重要,一旦交易過程中的數據被竊取,信息被篡改。不法分子就能夠獲得用戶、商戶交易的相關信息,并對交易過程的數據進行偽造、重放等攻擊。
本文針對移動支付中二維碼易偽造、易被篡改、變造,易攜帶木馬等問題,設計一套基于TOTP算法的動態二維碼支付方案,保證交易的不可為造性、實時性、唯一性、時效性、可認證性、完整性。
系統由多終端設備與云支付平臺組成,各終端通過設計的REST接口與云支付平臺進行交互。系統共分為三層:訪問層、服務層、資源層。總體系統框架如圖1所示。

圖1 移動安全支付系統總體架構
訪問層即訪問云端的方式,分別有手機APP、智能POS機、PC瀏覽器。
服務層是整個移動支付系統的核心,包含了云端支付系統的功能,包括:核心業務服務和基礎支撐服務。核心業務服務包含動態支付、風險評估、后臺管理、用戶模塊、商戶模塊、訂單模塊。基礎支撐服務包含簽名、通信、日志、密鑰管理、認證鑒權、加密解密等模塊。
資源層主要是存放移動支付系統信息的實體,使用關系型數據庫存儲賬戶信息、支付信息、商戶信息、商品信息等支付平臺數據。使用分布式緩存(Redis)對熱點數據進行緩存。隨著系統業務量增大,采用RabbitMQ作為消息系統,能夠解決數據投遞,非阻塞操作和推送通知,異步處理和工作隊列的問題等。針對一般文件存儲,可使用第三方存儲服務,利用主流CDN和自建CDN節點的優勢,在性能和成本之間尋求平衡。
1.2.1 動態支付功能設計
動態支付是移動云支付系統的核心部分,支付密鑰是標記交易的唯一標識符,只有商家通過發送訂單信息和客戶生成的支付密鑰才能申請交易。云端對支付密鑰進行認證后完成支付交易,支付流程如圖2所示。

圖2 支付流程
支付流程由兩個部分構成:
1) 支付二維碼產生 用戶在支付時產生的二維碼由基于時間規則算法動態生成的。在整個支付過程中支付二維碼每60 s生成一次,每個用戶的支付二維碼都是唯一的。二維碼有效時間在支付完成或超時立即失效。相對于靜態二維碼的易偽造、成本低、易竊取等缺點,動態二維碼能保證其不可為造性、實時性、唯一性、時效性、可認證性、完整性。
2) 支付密鑰認證 云移動支付系統收到交易訂單和支付密鑰后,要對密鑰進行基于時間的認證。先驗證是否在有效期內,然后通過TOTP算法[3]生成6位動態口令,將6位動態口令和時間戳合成的字符串通過哈希算法SHA-256生成動態支付密鑰[3]。當云端服務器接收到交易過程產生的動態支付密鑰后,根據支付訂單號查詢其所對應的TOTP中密鑰串K和時間戳,與當前時間生成支付密鑰并與用戶生成的支付密鑰進行驗證。如相同則交易正確,否則表明支付超時或被篡改偽造。
1.2.2 風險評估功能設計
用戶的風險評估是在商戶發送收款請求時進行的。針對用戶的個人信息、消費水平、消費時間、地點和習慣等方面進行安全性分析,評估當前消費是否為該用戶的正常購物行為。風險評估流程如圖3所示。

圖3 風險評估流程
系統采用樸素貝葉斯算法[4]與自定義規則匹配相結合的方式來實現支付風險評估。根據用戶交易過程中產生的樣本數據,提取特征值屬性,對用戶的支付行為行進分類。若結果異常,則交易不被允許,要求用戶進行二次身份認證。若結果正常則對用戶支付的相關數據進行規則匹配。自定義規則匹配用戶常用的地點、支付時間、支付金額等限制。如果在用戶預設范圍內則通過則允許支付,否則要求二次身份認證。
1.2.3 認證鑒權模塊設計
在移動云支付系統中認證鑒權包括:統一的認證服務和統一鑒權服務。
統一認證服務主要是在用戶執行操作時,提供我是我本人的身份證明[5]。常見的身份認證用戶名和密碼的輸入是存在被竊取的風險。現如今人臉識別、指紋、短信、聲紋是用戶認證主要方式。能夠有效地避免不法分子通過自動化工具進行密碼爆破和竊取。
統一鑒權服務是在用戶認證會話的維持和維護有效性[6]。大多數Web站點使用Session,其主要功能是保持會話信息,對用戶相關信息的存儲和對用戶進行驗證,而在移動系統中要使用Token來對用戶的身份鑒權。
認證鑒權主要流程如下:
1) 客戶端通過獲取登錄驗證碼請求提交用戶手機號獲取登錄驗證碼。
2) 云端支付平臺生成6位隨機驗證碼,通過第三方短信/語音平臺發送至用戶手機。
3) 客戶端得到短信/語音驗證碼后進行登錄請求。
4) 云端支付平臺短信/語音驗證通過后,云端支付平臺對用戶進行登錄地點/時間異常檢查。
5) 如果用戶不在常用的地點或不在常規時間段登錄,將會要求用戶輸入密碼進行二次身份認證。
6) 云端支付平臺驗證后通過相應的方法生成一個Token與該用戶進行關聯,并生成的Token返回給客戶端。
7) 客戶端在所有的請求中都需要攜帶Token進行認證,云端支付平臺通過解析Token來對客戶端進行身份檢測。
8) 當用戶退出登錄或在其他設備登錄時,之前的Token將會失效。
1.2.4 通信功能模塊設計
通信功能模塊是連接移動端和云端支付平臺的橋梁,用來保證用戶、商戶和云端支付系統之間信息傳遞的安全性。
為保證交易安全性,系統傳輸模式使用HTTPS協議,使用JSON格式作為數據的載體,對通信過程中關鍵數據進行加密操作。對JSON數據進行數字簽名,能夠有效地保證數據完整性、機密性和不可抵賴性。
在通信過程中采用AES加密數據,使用RSA密鑰對AES共享密鑰進行二次加密。云端支付系統為每一個用戶生成私鑰,而公鑰存儲在云端,具體加密方案設計流程如下:
1) 云端支付平臺隨機生成16個數字Key。
2) 云端支付平臺使用RSA公鑰將隨機生成的Key加密生成AESkey。
3) 云端支付平臺通過AES算法結合Key對關鍵數據加密。
4) 客戶端通過提取JOSN數據中AESkey,使用RSA私鑰對AESKey解出Key。
5) 客戶端通過AES算法結合Key對關鍵數據解密。
移動安全支付系統采用Android系統作為用戶客戶端,智能POS機作為商戶客戶端。整個云端支付系統使用Redis作為高速緩存,使用RabbitMQ作為消息隊列系統,完成各個模塊之間的通信,使用Celery作為任務分發模塊。
動態支付是整個移動支付平臺中關鍵的功能。當用戶在線下商店選完商品需要支付時,客戶端通過使用OKHttp發送支付請求。當云端支付系統驗證請求合法性后,通過從數據庫設定的Sequence中取出序列號和當前日期組成唯一的預支付訂單號和生成的16位隨機密鑰Key、當前時間戳存入數據庫并返回給用戶。
如圖4所示,客戶端接收到云端支付系統返回的數據后,客戶端利用本地共享密鑰和隨機密鑰生成新的密鑰K,通過TOTP算法生成了6位動態口令。之后利用哈希函數HASH-256對6位動態口令與云端返回的時間戳拼接成的字符串進行生成不可逆的支付密鑰。最后客戶端利用ZXing[8]將“預支付訂單號&支付密鑰”拼接成的字符串生成支付二維碼,支付二維碼隨著時間每60 s更換一次。

圖4 動態密鑰生成流程
云端支付系統在收到訂單信息后,通過查詢預支付訂單表,根據支付密鑰規則重新生成當前密鑰同訂單中的商戶上傳的支付密鑰進行比對。如果相同就通過事務處理扣除用戶相應的支付金額,增加商戶的資金。如果不相同,則返回支付失敗,并記錄。
該模塊由SciKit learn實現,它是一款數據挖掘和數據分析工具,擁有分類、回歸、聚類、降維等相關學習算法和模型[9]。
本文通過提取用戶支付地點、支付商戶名、支付商品數量、支付時間和支付金額這五個維度特征數據進行訓練,對系統支付過程的風險進行評估。
當商戶發出交易指令后,系統自動提取支付地點、支付商戶名、商品數量、支付時間和支付金額,使用樸素貝葉斯算法進行訓練樣本模型,最后對本次用戶支付行為進行支付風險判斷。
用戶行為通過了樸素貝葉算法的異常識別后,系統將再進行規則匹配。如果匹配不通過,則要求用戶輸入支付密碼,進一步確認身份,完成認證。
如圖5所示,系統生成6位隨機數后通過Celery異步發送給用戶,并設置過期時間存入緩存Redis中。

圖5 短信發送流程
返回的數據由三個屬性構成:用戶手機號、超時時間、驗證碼。將用戶手機號碼作為Key,驗證碼作為Value。云端支付系統直接從Redis中獲取號當前手機對應的驗證碼與用戶輸入進行驗證,驗證通過將用戶ID轉換生成攜帶身份信息的令牌值(Token ID)。具體過程如下:
1) JWT頭部header中typ為type縮寫,代表是JWT,alg表示加密方式為HS256,exp代表當前時間。
2) 在JWT的消息體playload中添加user_id和時間戳。
3) 簽名(Sign)。其過程如圖6所示,把header、playload分別使用Base64編碼,使用‘.’將經過編碼后的字符串進行連接,執行HMAC-SHA-256算法加密,對加密后的數據使用Base64編碼,生成簽名的字符串。

圖6 Sign過程
4) 生成Token。把Base64編碼后header和playload以及sign用‘.’連接起來即header.playload.sign,就生成了Token。
5) 校驗Token。首先用將字符串按‘.’切分三段字符串,分別得到header、playload和sign。然后將header.playload拼裝用密鑰和HAMC SHA-256算法進行加密然后得到新的字符串和Sign進行比對。如果一致數據正確,則從head取出exp對存活期進行判斷,如果超時則要求重新登錄,如果在存活期內返回user_id值。
用戶短信登錄認證成功后,系統將簽發兩個Token:
1) Token,短期證書,用于客戶端的正常服務請求所攜帶的認證信息。
2) Refresh Token,較長期的證書,用于Token失效后,自動申請新的Token所需攜帶的認證信息,不可直接用于服務請求。
分別給這兩個Token設置不同的有效期。在用戶退出登錄時通過客戶端將Token和Refresh Token進行銷毀。在Refresh有效期內,在Token過期時客戶端通過Refresh Token獲取新的Token。當Refresh過期后,需要用戶重新認證登錄。
TOTP(基于時間的一次性密碼算法)是支持時間作為動態因素基于HMAC一次性密碼算法的擴展[10]。
TOTP計算公式如下:
TOTP(K,C)=Truncate(HMAC-SHA-1(K,C))
(1)
式中:K是密鑰串(Base32字符串);C是時間戳。
C=(T-T0)/X
(2)
式中:T是當前時間戳;T0取值為0;X表示時間步長,默認是30 s。
HMAC-SHA-1是從 SHA1 哈希函數構造的一種哈希算法,HMAC將密鑰與消息數據混合,輸出長度為 160 位哈希。
Truncate是函數,實現如下:
1) 將密鑰串K與時間戳C通過HMAC-SHA-1加密,得到一個長度為20字節的密串。
2) 取出密串的最后一個字節的低4位,作為截取加密串的下標偏移量。
3) 按照下標偏移量開始,獲取4個字節,按照大端方式組合成一個整數。
4) 截取這個整數的后6位轉成字符串返回。
如圖7所示,因為TOTP的動態性,其中密鑰串K分別由靜態密鑰串key1和動態密鑰串key2組成。靜態密鑰串key1是客戶端與云端支付平臺的共享密鑰;動態密鑰key2是由云端支付平臺隨機生成并下發給客戶端。客戶端則通過TOTP算法生成6位動態口令,將生成的動態口令與時間戳相結合,最后通過哈希算法SHA-256生成動態支付密鑰。

圖7 TOTP算法的生成與認證
樸素貝葉斯(Naive Bayes)是貝葉斯算法中的分支之一,是常見的一種分類方法,簡稱NB算法[11]。公式如下:
(3)
式中:C為類別;X為待分類項;P(C|X)為X的狀態下是C的概率大小。求解過程如下:
1) 設置待分類項X={a1,a2,…,am},每個a為X一個特征屬性。
2) 確定類別集合C={Y1,Y2,…,Ym}。
3) 計算P(Y1|X),P(Y2|X),…,P(Yn|X)。
4) 如果P(Yk|X)=Max{P(Y1|X),P(Y2|X),…,P(Yn|X)},則X屬于Yk類。
如圖8所示,系統選取支付時間,支付地點、商戶、支付金額、支付商品數量五個維度作為特征屬性,設定用戶的支付地點為L,支付時間T,支付商戶S,支付商品G,支付金額M,即X={L,T,S,G,M}。

圖8 貝葉斯風險評估流程圖
將X代入式(3)運算:
(4)
結果如下:
(5)
式中:P(L|Y)正常支付情況下L的概率;P(L)為所有情況下L的概率。計算P(Y|X)支付正常為P(Yes),計算P(N|X)支付異常為P(No),如P(Yes)>P(No)則表明支付正常,反之則支付異常。
本系統中所需要的服務器采用騰訊云CVM服務器,整體部署方案如圖9所示。整個云端支付系統使用Nginx作為HTTPS服務器和反向代理,不僅可以提高Python的I/O處理能力,還可以緩沖響應,減輕后端壓力。Gunicorn作為Python應用服務器,易于配置管理,能夠按需求切換異步和同步工作模式。數據庫服務器采用MySQL,緩存服務器使用Redis,消息隊列使用RabbitMQ。Celery作為分布式任務隊列系統。

圖9 系統部署方案
1) 服務器端軟硬件配置環境:
(1) 服務器類別:騰訊云CVM服務器。
(2) 服務器機型配置:標準型S1;CPU:16核;內存:8 GB;硬盤:帶寬:100 Mbit/s。
(3) 操作系統:Ubuntu Server 16.04.1 LTS 64位。
(4) 應用服務器:Nginx 1.10.3 (Ubuntu),Gunicorn-19.8.1;Python 3.6。
(5) 數據庫系統:MySQL 5.6,Redis 3.2.9。
(6) 消息隊列系統:RabbitMQ 3.5.7-1。
(7) 分布式任務隊列:Celery 4.1.0。
2) 客戶端軟硬件配置環境
客戶端使用安卓(Android)系統作為運行終端。運行配置如下:
(1) 手機型號:ONEPLUS A3010;
(2) 安卓版本:Android 7.1.1;
(3) 運行內存:6 GB;
(4) 存儲內存:128 GB。
云端系統搭建完成后,在兩部手機上安裝移動支付APP。一部充當普通用戶,另一部當作商戶,分別注冊各自賬號。用戶在需要購買商品時,在商家確定商品后,用戶只在需要支付的時候打開支付二維碼,商家進行掃描二維碼收款。其中二維碼每60 s更新一次,動態更新達到了基本的設計需求。系統運行如圖10所示。

圖10 系統運行
4.2.1 測試指標
本系統測試分為風險評估測試、主要功能測試與性能測試。
風險評估測試利用樸素貝葉斯算法在實驗環境進行訓練,對用戶的異常支付行為進行識別和匹配。
功能測試主要使用黑盒測試[12],通過各個功能編寫測試用例,按照測試用例進行測試,驗證結果的正確性。檢查系統各個功能是否能夠滿足生成環境需求,包括短信登錄認證、密鑰生成分發、機密信息加密解密、動態支付密鑰生成與認證、風險評估等功能模塊。
性能測試通過自動化的測試工具來對系統的各項性能指標進行測試[13]。系統性能測試主要測試系統的高并發性能,包括:平均響應時間、每秒處理請求數量、平均流量和錯誤率等。
4.2.2 風險評估測試
在實驗環境下使用樸素貝葉斯算法進行訓練,通過統計兩個用戶的購物數據,分別訓練或測試使用的白樣本和黑樣本。通過人工標簽Label(0為正常,1為異常)共600條,其中150份為異常樣本,450份為正常樣本,部分訓練樣本如表1所示。

表1 訓練樣本
通過Scikit-Learn中的GaussianNB函數進行訓練,采用拉普拉斯平滑法,對每個分量x的計數加1可以避免零概率問題。
實驗將數據樣本分為3份,采用3折交叉驗證,兩份為訓練集,另一份為測試集。具體異常判斷結果統計如表2所示。

表2 判斷結果統計表
對樣本數據進行打亂,再次進行三次3折交叉驗證。具體數據如表3所示。

表3 三次3折交叉驗證統計表
經測平均準確率能達到80%以上,召回率在84%左右,綜合標價指標均達0.8,而且數據都比較平穩,沒有太大的浮動。可以看出樸素貝葉斯算法在一定程度上能有效地辨別異常支付的能力,再結合移動支付系統的自定義匹配規則,能夠對大部分的危險支付行為進行預警,有效地保障用戶的資金安全。
4.2.3 主要功能測試
Token獲取、密鑰更新、生成測試、風險評估功能測試,如表4所示。

表4 功能測試用例
4.2.4 性能測試
本系統性能測試主要測試系統的高并發性能,包括:平均響應時間、每秒處理請求數量、平均流量和錯誤率等。具體測試用例如表5所示。采用專業測試工具Apache Jmeter[14],用于壓力和性能測試,測試結果如表6所示。

表5 性能測試用例

表6 性能測試表
根據測試數據看出系統整體性能良好,在網絡狀態良好的情況下延遲較低,響應及時,能正常運行。
本文為移動云安全支付設計了一套可靠的解決方案。通過與TOTP算法相結合設計出一種新型動態二維碼支付方式,保證二維碼的不可偽造性、唯一性、時效性等安全性;通過改進現有的JWT協議建立完整的認證鑒權模式;在通信過程中,采用數字簽名確保數據的完整性、安全性,同時具有不可抵賴性和防止重放等功能;采用了一種基于樸素貝葉斯算法和自定規則的風險評估模型,經過測試能夠在一定程度上提升移動支付系統的安全性。