微信和支付宝离线付款码,动态密码保护器实现原理探索(1)

网易将军令是一种动态的密码保护器,还有赛门铁克的vipAccess也是一种动态密码保护器。

它们的特点是可以离线动态生成,同时每过一分钟或者半分钟之后,密码都会变化一次,是一个六位数的密码。
这个密码的用途是在你输入你的账号加上固定密码之后,还需要额外输入一个动态密码。这个就是上面说的动态密码。其中网易将军令是用在网易游戏上的,赛门铁客的vipAccess是用在企业登录的二次验证的。

当初小时候我以为网易将军令是通过发短信啥的,现在看来其实并不是,是可以做到在离线情况下动态生成密码的。

微信支付和支付宝的付款码都是支持离线支付的,也就是你在没有网络的情况下,也可以使用付款码。

我把它们称为offline token(离线凭据)。

示例图片:


image.png
image.png

今天的文章主要是讲一下我自己对offline token实现的一种思路,供大家参考。当然我也不是这些企业的员工,也不清楚它们真正使用的技术细节。主要是如果让我来实现上面的功能,我会怎么做。

如果有不同的想法,欢迎评论和我探讨,谢谢。

接下来讲第一种离线token的实现方式:

第一种离线token需要服务器和客户端使用相同的加密算法和逻辑,以时间作为加密内容,实现动态密码

具体的实现逻辑就是,将军令使用内置的秘钥,根据当前的时间当前时间可以是半分钟级别的,也可以是分钟级别的,使用加密算法和哈希算法生成一个6位数的动态密码。在验证的时候,服务器查找账户对应的将军令秘钥,使用同样的逻辑和算法得到一个6位数的动态密码,如果可以匹配则验证通过。需要服务器和将军令的时间误差要尽可能越小越好。

这里以AES加密算法为例,也可以用其它类型的加密算法。

将军令在出厂的时候,这个将军令的设备肯定是和你的游戏账户绑定的,将军令里面肯定内置了加密的秘钥的。
因此可以在数据库里记录将军令使用的秘钥和游戏账户,把这两个关联起来。

这里用python举个例子

下面是简单的aes算法:

# 补足字符串长度为16的倍数
def add_to_16(s):
    while len(s) % 16 != 0:
        s += '\0'
    return str.encode(s)  # 返回bytes


class Aes:
    def __init__(self, key):
        self.key = add_to_16(key)
        self.aes = AES.new(str.encode(key), AES.MODE_ECB)

    def encrypt(self, content):
        return str(base64.encodebytes(self.aes.encrypt(add_to_16(content))), encoding='utf8').replace('\n', '')  # 加密

    def decrypt(self, content):
        return str(
            self.aes.decrypt(base64.decodebytes(bytes(content, encoding='utf8'))).rstrip(b'\0').decode("utf8"))  # 解密

假设将军令出厂内置的秘钥是08408d58982111e9b729a0999b140833,用户的游戏id是iamdev,那么在出厂的时候,网易的游戏数据库就会记录下iamdev绑定了一个将军令设备,秘钥是08408d58982111e9b729a0999b140833

那么怎么形成一种每隔一分钟就会变化一次的效果呢?

可以使用当前unix的时间戳,然后精确到分钟即可,获取到秒级的时间戳之后,使用

t = t-t%60即可获取到一个分钟级别的时间戳,这样的话,将军令在

12点53分23秒加密的结果和12点53分45秒加密的效果是一样的,因为都会被精确到分钟级别,也就是12点53分00秒

if __name__ == '__main__':
    t = int(time.time())
    t = t - t % 60
    print(t)
    key = "08408d58982111e9b729a0999b140833"
    print(str(key))
    aes = Aes(str(key))
    encrypt_text = aes.encrypt(str(t))
    print('加密值:', encrypt_text)
    print('解密值:', aes.decrypt(encrypt_text))
    

上述测试打印的结果是

1561560480
08408d58982111e9b729a0999b140833
加密值: BBJxBAUnVVucCALYRLyJ5A==
解密值: 1561560480

怎么获取到一个6位数的数字呢?

借助python的hash函数即可实现,因为python的hash函数可能会返回负数,所以取的区间是1:7。

print(str(hash(encrypt_text))[1:7])
#098182

在二次验证的时候,将显示的动态密码输入,发送到服务器。服务器通过在数据库里面查找这个账号对应的将军令的秘钥,然后使用相同的加密算法和哈希算法计算获取到数字,如果一样的话,那就是验证通过。

只要服务器上的时间和将军令设备的时间差不超过一分钟,都可以验证通过。

举个例子,如果将军令当前的时间为8点54分23秒,而服务器的时间是8点54分25秒,都是可以验证通过的。

即便有人记住了你的动态密码,但是他下次登录是没法使用的,因为每次生成的动态密码都是不一样的

下次登陆的时候的时间就不是那个时间了,而且时间差远大于一分钟。

除此之外,如果为了允许一定范围的时间误差,服务器是可以往前或者往后计算多一分钟都是可以的。

上面的逻辑其实也是对应VIP Access的。

我自己亲自测试过VIP access的客户端,如果把网络断开,然后来回kill掉,并重新打开客户端,发现这个6位数是一样的。因此明显是和当前时间是有关联的。

从安全角度来说,将军令出厂内置了秘钥,而且黑客是不知道你的秘钥的,所以是很安全的。而且黑客只能使用网络攻击,黑客和第三方是无法通过网络窃取你的将军令的秘钥的,而且这个设备也是在你身边,也是无法被窃取的。

其实扩展开来想的话,是可以思考清楚类似银行的动态密码保护器怎么做的?
usb u盾,用户在拿到的时候,是需要首次初始化,连接到电脑,然后从银行下载私钥的。

当然如果网易自己的服务器被黑了导致秘钥泄露的话,那其实也不是用户的问题。

未完待续,下一章节讲一下微信支付和支付宝支付的离线付款码的思路。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350