原标题《离线二维码产品技术方案》,是我加入翼支付来第一份和技术有关的文档。
一、产品定义
离线二维码是翼支付客户端付款码功能在网络状况差的环境下实现用户身份验证的产品。它可在初次登陆后,在无网络状态下生成实时更新的二维码,通过商家的扫码枪可实现验证。
二、技术原理
离线二维码的技术原型是在行业中广泛使用的一次性口令(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: