离线二维码的技术原型是在行业中广泛使用的一次性口令(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过以后通知服务端降低该用户的消费限额。
参考:http://www.cnblogs.com/wensz/p/4934438.html
NSData->Byte数组
iOS sha1加密方法(哈希算法,用于校验数据完整性)以及字符串中含有汉字的情况的加密方法
首先需要添加头文件
#import<CommonCrypto/CommonDigest.h>
然后直接使用下面的方法就可以了
//sha1加密方式
- (NSString *) sha1:(NSString *)input
{
//const char *cstr = [input cStringUsingEncoding:NSUTF8StringEncoding];
//NSData *data = [NSData dataWithBytes:cstr length:input.length];
NSData *data = [input dataUsingEncoding:NSUTF8StringEncoding];
uint8_t digest[CC_SHA1_DIGEST_LENGTH];
CC_SHA1(data.bytes, (unsigned int)data.length, digest);
NSMutableString *output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
for(int i=0; i<CC_SHA1_DIGEST_LENGTH; i++) {
[output appendFormat:@"%02x", digest[i]];
}
return output;
}
Byte
NSString
for(int
{
NSString
if([newHexStr
hexStr = [NSString
else
hexStr = [NSString
}
NSLog(@"bytes