文末留言送书5本

现在生活已经离不开微信/支付宝电子支付,平常出去吃饭、购物只要带个手机,就可以解决一切,以致于现在已经好久没摸过真????了。

有一次出去吃饭,排着队付钱,等着过程非常无聊,准备拔出手机来把荒野乱斗,却发现这个地方竟然连不上网 。

看着手机明明信号满格,但是就是显示网络无连接,苹果手机用户痛,谁用谁知道。

画外音:真的要 Diss 一下使用英特尔基带的 Iphone,????好差,没事网络就会闪断~

说回正题,由于没有网络,而我又没带钱,所以就怕付钱的时候因为手机没网,没办法使用支付宝扣款。正想着时,已经排到了我,不管三七二十一,先用下支付宝试试,实在不行就不吃了。

不过没想到,当商家用扫码抢扫描支付宝上付款码支付以后,虽然我的手机最终没有弹出支付成功的页面,但是商家端显示支付成功,并成功打印出了小票,过了一会,我的手机收到支付宝扣款短信。

因为我最近的工作对都是与微信/支付宝有关,整体支付流程还是比较清楚,但是付款码为什么能离线支付确实不是很清楚,所以研究了一番,于是有了今天的文章。

科普支付方式

在聊付款码离线原理之前,我们先给不熟悉支付宝/微信支付方式同学先科普一下常见的两种支付方式。

微信、支付宝线下支付常用支付方式有两种,一种是我们打开手机,主动扫描商家提供码牌,这种支付方式一般称为主扫支付(用户主动扫码)。

以支付宝为例,付款流程如图所示:

图片来自支付宝官网

第二种则是我们打开手机,展示我们的付款码,然后商家使用扫码枪等工具获取付款码完成支付,这种支付方式一般称为被扫支付(用户被扫码)。

以支付宝为例,付款流程如图所示:

图片来自支付宝官网

对于第一种方式,需要手机端 APP 扫码,然后弹窗确认付款,这种方式是没有办法在手机没有网络的情况完成支付,所以我们上文说的没有网络的情况特指付款码支付的场景。

付款码付款流程

在聊付款码离线支付的前提前,我们先来来看下付款码的整体流程,以超市购物为例,一次付款码的支付信息流如图所示:

参考知乎@天顺

这个过程商家后台系统是需要调用的支付宝条码支付的接口,完成支付。

「由于商家后台需要在线联网与支付宝后台通讯,所以说付款码的离线支付,指的是客户端没有的网络的情况,商家端其实必须实时联网在线。」

一次付款码接口调用流程如图所示:

来自支付宝官网

通过上面两张图,我们整体了解付款码交互流程。

付款码的技术方案其实可以分为客户端在线与离线的两种情况,下面我们来看下两种方案具体实现方式。

在线码方案

客户端在线码的方案,这个应该比较容易想到,只要支付宝/微信在登录的情况下,点击付款按钮,客户端调用后台系统的申请付款码接口。

后台系统受到请求之后,生成一个付款码,然后在数据库保存付款码与用户的关系,并且返回给客户端。

只要客户端在有效期内展示该付款码,就可以完成支付,否则该二维码就将会过期。

使用这种方案,相对来说比较安全,因为每次都是服务端生成码,服务端可以控制幂等,没有客户端伪造的风险的。

另外即使需要对付款码规则调整,比如付款码位数增加一位,我们只要调整服务端代码即可,客户端都无需升级。

「不过这种方案缺点也比较明显,客户端必须实时在线联网,没有网络则无法获取付款码。」

另外,现在有一些智能设备也开始支持支付宝支付,这些设备中很大一部分是没有联网的功能(比如小米手环四),那这种情况是没办法使用在线码方案。

基于这种情况,所以开始有了离线码方案。

离线码方案

说起离线码大家可能比较陌生,但是实际上你如果仔细观察,其实很多场景都用到了离线码。

比如说以前去黑网吧玩梦幻西游的时候,账号总是被盗。

没办法,花了一笔重资买了一个网易将军令,每次登录的时候,除了输入用户名与密码以外,还需要输入动态口令。从此账号就很少被盗了。

又比如说每次网易支付的时候,我们除了输入银行卡密码以外,还需要输入网银盾上动态码,这样才能完成支付。

画外音:
这里又要吐槽一下,网银盾以前真的超难用,动不动就驱动不兼容。还记得当初用网银充值黄钻,搞了一下午都没有成功--!

当然上面这些可能已经是老古董了,很多人都可能没用过,现在比较流行是「手机验证器APP」,比如 「Google Authenticator」 等。

这种令牌器,动态产生一次性口令(「OTP, One-time Password」),可以防止密码被盗用引发的安全风险。

其实付款码离线方案技术原型就是基于这种方案,所以下面我们就基于 Google Authenticator,来了解一下这其中的原理。

动态口令技术原理

首先如果我们需要使用 「Google Authenticator」,我们需要在网站上开启二次验证功能,以 Google 账号为例,在设置两步验证的地方可以找到如下设置:

当我们点击设置,将会弹出一个二维码,然后使用 「Google Authenticator」 APP 扫码绑定。

当我们绑定之后, 「Google Authenticator」 APP 将会展示动态码。

我们来解析一下这个二维码,对应下面这个字符串:

otpauth://totp/Google%3Ayourname@gmail.com?secret=xxxx&issuer=Google

上面的字符串中,最重要就是这一串密钥 secret,这个是一个经过 「BASE32」 编码之后的字符串,真正使用时需要将其使用「BASE32」 解码,处理伪码如下:

original_secret = xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
secret = BASE32_DECODE(TO_UPPERCASE(REMOVE_SPACES(original_secret)))

「这个密钥客户端与服务端将会同时保存一份,两端将会同样的算法计算,以此用来比较动态码的正确性。」

我们以客户端为例,生成一个动态码,首先我们需要经过一个签名函数,这里 **Google Authenticator **采用的 「HMAC-SHA1」,这是一种基于哈希的消息验证码,可以用比较安全的单向哈希函数(如 SHA1)来产生签名。

签名函数伪码如下:

hmac = SHA1(secret + SHA1(secret + input))

上面函数中的,input 使用当前时间整除 30 的值。

input = CURRENT_UNIX_TIME() / 30

这里时间就充当一个动态变参,这样可以源源不断产生动态码。

「另外这里整除 30,是为了赋予验证码一个 30 秒的有效期。」

这样对于用户输入来讲,可以有充足时间准备输入这个动态码,另外一点客户端与服务端可能存在时间偏差,30 秒的间隔可以很大概率的屏蔽这种差异。

画外音:这个有效时间其实很考量,如果比较长,安全性就差。

如果比较短,用户体验就很差,不容易输入准备。

经过 「HMAC-SHA1」 签名函数以后,我们得到一个长度为 40 的字符串,我们还需要将其转化为 6 位数字,方便用户输入。处理的伪码如下:

four_bytes = hmac[LAST_BYTE(hmac):LAST_BYTE(hmac) + 4]
large_integer = INT(four_bytes)
small_integer = large_integer % 1,000,000

完整的算法伪码如下:

original_secret = xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
secret = BASE32_DECODE(TO_UPPERCASE(REMOVE_SPACES(original_secret)))
input = CURRENT_UNIX_TIME() / 30
hmac = SHA1(secret + SHA1(secret + input))
four_bytes = hmac[LAST_BYTE(hmac):LAST_BYTE(hmac) + 4]
large_integer = INT(four_bytes)
small_integer = large_integer % 1,000,000

当客户端将动态码上传给服务端,服务端查询数据库获取到用户对应的密钥,然后使用同样的算法进行处理生成一个动态码,最后比较客户端上传动态码与服务端生成是否一致。

付款码离线方案

上面我们了解了动态口令的实现方案,付款码生成原理其实也大致如此。

不过付款码离线方案采用动态密钥的方式(「全局唯一」),定时请求服务端更换密钥,以此保证更高的安全性。

另外在一次性动态口令方案,需要双方基于同样的秘钥,所以服务端需要明确知道这「背后正确用户」。以上面的登录场景为例,登录过程输入用户名,服务端就可以根据这个在数据库中查询相应的密钥。

但是在付款码的支付场景中,支付过程仅仅传递一个付款码,就可以向相应的用户扣款。不用想,这个付款码这串数字一定包含相应的用户信息。

所以付款码的相应的算法相比动态码会更加复杂,这样才可以有效保证安全性。

看到这里,不知道你们是否急切想了解这套算法那?

哈哈,开个玩笑,这种算法岂能是我们能掌握的。

支付宝核心算法咱不知道,但是我们可以从其他人公开设计方案了解一个皮毛。

这里小黑哥给你一个知乎网友@反方向的钟回答的离线二维码实现方式,给你 look look。

来自:https://www.zhihu.com/question/49811134/answer/135886638

付款码离线码的劣势

最后我们来看下付款码离线方案的劣势:

第一,算法调整不灵活,如果相关算法较大的调整,可能需要升级客户端,并且这个期间服务端还需要兼容新老算法产生的付款码。

第二,安全性问题,正常的情况相关密钥无法被普通用户获取,但是架不住有有心之人。他们可能通过获取手机用户 Root 权限或者越狱手机,利用恶意程序获取密钥,然后随意生成付款码。

看到这一点,大家可能会担心自己的钱包安全了。不过这一点,我觉得不过过分担心,蚂蚁集团这么多大神,不是吃干饭的,他们肯定有很多措施保证支付安全。

第三数据碰撞问题,A 用户生成付款码算出来与 B 用户一致,这就 Hash 算法一样,再怎么优秀的算法,也有概率才生一样的额 Hash 值。

这就导致原本是扣用户 A 的钱,最后却扣了 B 用户。这样一来,确实很乌龙,对于 B 用户来讲,莫名其妙被扣钱了。

不过放心,这种事放到放到现在,我觉得还是比买彩票中奖低,所以这种事还是不用过分担心了。

即使真被误扣了,放心,支付宝这么大体量肯定会跟客户赔钱的。

最后

最后总结一下,我们平常使用付款码支付,其实原理就是商家端获取我们手机 APP 付款码(「其实就是一串数字」),然后后台调用支付宝支付接口完成扣款。

这个流程商家端后台程序必须联网在线,但是对于我们客户端来讲可以在线,也可以离线。

如果我们客户端在线,那就可以通过服务端向客户端发送付款码,这种方式更加安全,灵活,但是对于弱网环境下,体验就很差。

如果我们客户端没网,那就通过客户端通过一定算法生成付款码,服务端收到经过相关校验,确认是哪个用户,确认码有效性,并且完成扣款。这种方式,适合客户端没有网络的情况,不过相对不灵活,且安全性稍差。

嘿嘿,了解原理,有没有觉得还是挺有意思的~

下次排队付款钱,如果手机没网,不要担心尴尬,放心拿出手机付钱~

对了,看完记得一键三连,这个对我真的很重要。

参考

  1. https://www.zhihu.com/question/49811134/answer/135886638

  2. https://garbagecollected.org/2014/09/14/how-google-authenticator-works/

赠书福利

赠送新书《Python Web开发从入门到精通》共5本,刚刚上架!由「北京大学出版社」赞助提供,Python神书 ,感兴趣的朋友推荐入手一本。

本书分为3部分:第1部分是基础篇,带领初学者实践Python开发环境和掌握基本语法,同时对网络协议、Web客户端技术、数据库建模编程等网络编程基础深入浅出地进行学习;第2部分是框架篇,学习当前*流行的Python Web框架,即Django、Tornado、Flask和Twisted,达到对各种Python网络技术融会贯通的目的;第3部分是实战篇,分别对几种常用WEB框架进行项目实践,利用其各自的特点开发适用于不同场景的网络程序。

参与方式:本篇文章底部「点赞」+「在看」+「留言」,文章内容相关的优质留言才可上墙!留言点赞数量最多前5位读者将获得这本书,30天内不能重复中奖,截止时间隔天推文之前,最终获赠者添加我的微信领取。

PS:禁止恶意刷赞!发现后将进入黑名单,取消上墙资格。

小猿微信
扫码加好友,给你能拉个学习群
????分享、点赞、在看,给个三连击呗!????

支付宝不用网络,也能正常支付,太神奇了吧!相关推荐

  1. 互联网晚报 | 9月30日 星期四 | 五菱与B站跨界合作;支付宝向“云闪付”开放支付场景;平安健康险上线“药划算”...

    ‍ ‍今日看点 ✦ 淘宝联盟宣布私域营销升级,今年双11将发10亿元补贴 ✦ 万达广场正式迈入400+时代,年客流超60亿人次 ✦ 蔚来换电站总数突破500座,预计年底超过700座 ✦ 五菱与B站跨界 ...

  2. 网络学习提要,真是太全了

    转自:http://blog.csdn.net/shuibaiz/article/details/8924326 目录: 第1章 交换技术 第2章 网络体系结构及协议 第3章局域网技术 第4章广域网技 ...

  3. VB6 简单实现 支付宝二维码扫马支付

    VB6 简单实现 支付宝二维码扫马支付 完整源码如下 Private Declare Function 初始化 Lib "alipay.dll" (ByVal 服务器 As Str ...

  4. 支付宝当面付之扫码支付“无效签名”

    做支付宝的当面付扫码支付的时候,遇到最纠结的问题就是一直提示"无效签名",然而官方又没有给出很明确的说明,在网上搜索了很长时间,也没有找到解决的具体例子,我就把我的经历说一下,有需 ...

  5. 微信、支付宝二码合一扫码支付实现思路

    一.支付二维码(预订单) 根据需要购买的信息创建预订单,将订单信息保存到Redis中,并设置有效期,注意生产二维码的链接后的参数可以关联到Redis中的key: QRCode  为servlet扫码请 ...

  6. 支付宝微信推出高速收费新服务器,微信、支付宝启动高速收费无感支付

    原标题:微信.支付宝启动高速收费无感支付 高速通行费可用支付宝.微信支付 当你还在惊叹手机支付带来的改变时,微信.支付宝却已经开始让支付脱离手机了!目前,微信.支付宝已同时宣布:启动高速"无 ...

  7. 对接支付宝服务商当面付手机网页支付

    一.前期准备: SpringBoot对接支付宝当面付和手机网站支付_springboot 支付宝当面付_Biubiubiuexo的博客-CSDN博客 配置成功后获得到我们开发需要的:支付宝公钥.商户私 ...

  8. 太神奇了!使用C#实现自动核验健康码:(2)OCR识别

    前言 上次太神奇了!使用C#实现自动核验健康码:(1)二维码识别,我们已经实现了识别健康码的颜色,但是健康码的内容不包含时间属性.那么使用图片就可以通过检查,肯定是不合适的. 因此,我们还需要读出健康 ...

  9. 7 11 藏尾诗c语言,为你写诗:11种杂体诗,汉语太神奇

    原标题:为你写诗:11种杂体诗,汉语太神奇 胸藏文墨怀如谷,腹有诗书气自华 杂体诗通指古典诗歌格律体以外的各种各样的诗体. 这些诗多把字形.句法.声律和押韵加以特殊变化,成为独出心裁的奇异之作,一般带 ...

最新文章

  1. 赋值语句和赋值表达式
  2. 目标检测--Enhancement of SSD by concatenating feature maps for object detection
  3. Unix调试的瑞士军刀:lsof
  4. Oracle三级联动单表地址数据
  5. hdu 5055(贪心)
  6. 21 RadioGroup ListFragment
  7. Linux SSH远程管理故障如何排查?
  8. 零基础学习什么编程语言比较合适?别的不说,听说大佬都学了这个!
  9. 【复习笔记】Cache的映像方法
  10. 【转】互联网架构的三板斧
  11. 快播(QvodPlayer)最新版 v5.20.234 官方版
  12. spring事务和加可重入锁解决库存超卖遇到的问题
  13. swift3 下标subscript
  14. 实习僧——数据分析岗招聘信息爬取 源代码
  15. 双吉他伴奏配合的有关问题
  16. 计算机更改锁屏密码忘记了怎么办,win10锁屏密码忘记了怎么办_w10忘记锁屏密码的处理步骤...
  17. SQL模糊查询时LIKE怎样跟变量
  18. 阿里云服务器常用配置收费1核2G/2核4G/4核8G/8核16G多配置
  19. imgui Study
  20. latex画三线表模板

热门文章

  1. QTP学习笔记,六月十号
  2. 微信实现秒回以及控制电脑
  3. java如何解决栈溢出问题_怎样解决栈溢出
  4. 【报告分享】2021年春节档电影报告-艺恩(附下载)
  5. 大过年睡不着,聊聊云开发入门
  6. 你家的WIFI还是你的吗?还是变成了不法分子的摇钱树?
  7. WebView手机屏幕(图片适应屏幕的宽度)适配的多种方式
  8. 好未来23届校园招聘开始了~靠谱内推
  9. 关于《白鹿原》的所思所想
  10. stm8lLCD显示