微信支付-Https与代理

Posted 移动开发技术

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微信支付-Https与代理相关的知识,希望对你有一定的参考价值。

  • 微信支付-Https与代理

    • http proxy

    • tcp proxy

    • apache/nginx

    • squid

    • 简单与交互,客户端证书

    • 微信支付支持的TLS版本

    • 微信支付的证书与有效期

    • 信任链,CA

    • 域名与证书

    • 测试网络设置

    • 简单

    • 交互

    • SSL/TLS,HTTPS

    • 代理设置

一个到某网站的HTTPS连接可被信任,当且仅当:

  • 用户相信他们的浏览器正确实现了HTTPS且安装了正确的证书颁发机构;

  • 用户相信证书颁发机构仅信任合法的网站;

  • 被访问的网站提供了一个有效的证书,意即,它是由一个被信任的证书颁发机构签发的(大部分浏览器会对无效的证书发出警告);

  • 该证书正确地验证了被访问的网站(如,访问https://example.com时收到了给example.com而不是其它组织的证书);

  • 或者互联网上相关的节点是值得信任的,或者用户相信本协议的加密层(TLS或SSL)不能被窃听者破坏。

SSL/TLS,HTTPS

WIKI: 传输层安全协议(https://zh.wikipedia.org/wiki/傳輸層安全協議)

WIKI: 超文本传输安全协议(https://zh.wikipedia.org/wiki/超文本传输安全协议)

简单与交互,客户端证书

简单

简单策略即传输只使用服务端证书+协商加密。一般来说,只要网络请求库支持TLS,就可以自动实现这个功能。

微信支付中除了资金敏感的接口以外,大部分都是这个策略。

具体请看接口说明中,关于是否需要证书的地方。

交互

参考示意图(https://zh.wikipedia.org/wiki/傳輸層安全協議#/media/File:SSL_handshake_with_two_way_authentication_with_certificates.svg)

交互策略,也叫双向证书。除了使用服务器证书,客户端也必须使用特定的证书,才能和服务器交换秘钥,完成握手。

微信支付中,退款,发红包,企业付款,撤销等接口,使用的是这个策略。

具体请看接口说明中,关于是否需要证书的地方。

微信支付支持的TLS版本

参见微信公众平台公告(https://mp.weixin.qq.com/cgi-bin/announce?action=getannouncement&key=1414562353&version=11&lang=zh_CN)

微信支付要求TLSv1.0及以上的版本。

(公众平台和开放平台也是一样的版本要求)

微信支付的证书与有效期

参见: 微信支付安全规范(https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3)

信任链,CA

HTTPS的安全性,还涉及一个归纳问题:

  1. 只要公钥能解密,那么信息就是安全的

即逆推还要满足:

  1. 公钥必须是安全的

要证明公钥是安全的,使用的是背书的方式,即由另一个证书来保证这个证书的有效性。

那么最基础的那个证书就叫根证书。

一般来说,根证书是跟着ssl库一起分发的。更新ssl库就可以获得最新可信任的根证书。

在没有办法更新的情况下,微信支付的证书的根证书,也打包在压缩包里,可以选择导入(即手动信任根证书)。

域名与证书

证书和域名是强相关的。

这是由于互联网请求会有钓鱼问题。也就是公钥是安全的,加密也是安全的,但是请求目标却是假的。

https库在连接目标的时候,会验证目标的证书和本地请求的域名是否一致。

解决这个问题的方法一般是在hosts当中给这个ip绑定一个域名。或者设置本地请求的时候不要验证此项。

测试网络设置

curl -k -d "@add_merchant.txt" --key "apiclient_key.pem" --cert "apiclient_cert.pem" https://api.mch.weixin.qq.com/secapi/mch/submchmanage?action=add

代理设置

为https请求设置代理非常复杂,主要是由于代理本身相当于是中间人的角色。

代理本身是分层的,通常的代理叫http代理,是在http协议层进行代理和转发。也就是说像这样:

client<--http(s)--> proxy <--http(s)--> server

对于简单策略的https,这样做问题不大,因为对服务器而言,代理就相当于客户端,实际客户端不可见。而代理和实际客户端之间可以选择http请求,这样虽然客户端想请求微信服务器,实际请求的却是代理,不会发生域名不一致的错误。

但是对于交互策略的https就会产生问题:实际报文到微信服务器的时候,必须已经被加密。但是如果是实际客户端加密,proxy就无法工作。所以客户端的证书只能部署在代理上,缺点会很明显:

  1. 证书安全多了个地方需要维护,而且暴露在外网。

这个时候有个比较少见的代理可以解决这个问题,即tcp代理。也就是tcp端口转发,还有地方会叫反向代理。

tcp代理不需要关注http包内容,不存在拆包。所以ssl加密可以由客户端完成。也就解决了上面的两个缺点:

  1. 证书放在实际客户端。

  2. 客户端代码即可以控制证书切换。

但是tcp代理确实相关文档较少,尤其是关于高性能要求环境下如何动态伸缩的指导较少。

http proxy

apache/nginx

nginx的proxy文档:ngx_http_proxy_module(http://nginx.org/en/docs/http/ngx_http_proxy_module.html

squid

ssl bump(https://wiki.squid-cache.org/Features/SslBump)

tcp proxy

我实现的微信支付专用tcp proxy,相当于是个demo: https://github.com/btbxbob/wxpay-reverse-proxy

nginx的tcp proxy扩展,注意需要重新编译nginx:https://github.com/yaoweibin/nginx_tcp_proxy_module



以上是关于微信支付-Https与代理的主要内容,如果未能解决你的问题,请参考以下文章

App内H5方式微信、支付宝支付,无法回跳到App问题

微信支付相关

微信分享与支付专项课程(公众号小程序小程序云)

#WordPress小技巧#纯代码为自己博客添加支付宝/微信打赏功能

ApiPHP与微信公众号支付,很简单

微信支付——微信公众号内支付 代码