原標題《離線二維碼產品技術方案》,是我加入翼支付來第一份和技術有關的文檔。
一、產品定義
離線二維碼是翼支付客戶端付款碼功能在網絡狀況差的環境下實現用戶身份驗證的產品。它可在初次登陸后,在無網絡狀態下生成實時更新的二維碼,通過商家的掃碼槍可實現驗證。
二、技術原理
離線二維碼的技術原型是在行業中廣泛使用的一次性口令(OTP, One-time Password),使用了該技術的產品除了有支付寶和微信,還有銀行U盾、游戲令牌等硬件設備。
在翼支付的離線二維碼上,方案的設計概述為:
1、 登錄翼支付,服務器生成唯一token,通過加密方式(如https)傳遞到客戶端。
2、 打開付款碼時,本地生成一段含有token與當前時時間戳的哈希值,如sha1(token+UnixTimestamp),轉換為byte[]並截取指定長度后轉換為int變量otp。
3、 設翼支付用戶賬號(手機號)為int變量id。
4、 設otp在[0,n]中,通過code=id*n+otp,即可將OTP與ID合並在同一個數字里,成為最終的條形碼/二維碼,並每間隔指定時間更新一次。
5、 通過商家掃碼槍掃描,服務端獲取了code,通過(int)(code/n)就得到了id,通過code%n就得到了otp。
6、 通過id找到token,通過當前時間戳與前后若干個相同間隔的時間戳以步驟2相同的方法生成對應的一組otps[],用於容許客戶端和服務端之間的時間差。
7、 將從客戶端得到的otp與otps[]中的元素逐一比對,如有相同項,則為驗證通過。
三、關於安全的討論
離線二維碼安全,核心就是在token的保密。
1、 傳輸:token的傳輸經過加密,可防止傳遞過程中數據包被截取。
2、 保存:token保存在app的獨立空間中可能會被惡意程序獲取到,這個問題理論上僅存在於已開放root權限的手機中。在產品安全的角度,只能限制root手機用戶使用,解決辦法可以是當客戶端獲知用戶的手機root過以后通知服務端降低該用戶的消費限額。
四、參考開源方案:
Google authenticator :
https://github.com/google/google-authenticator
LinOTP: