支付-Https与代理
http proxy
tcp proxy
apache/nginx
squid
简单与交互,客户端证书
支付支持的TLS版本
支付的证书与有效期
信任链,CA
域名与证书
测试网络设置
简单
交互
SSL/TLS,HTTPS
代理设置
一个到某网站的HTTPS连接可被信任,当且仅当:
用户相信他们的浏览器正确实现了HTTPS且安装了正确的证书颁发机构;
用户相信证书颁发机构仅信任合法的网站;
被访问的网站提供了一个有效的证书,意即,它是由一个被信任的证书颁发机构签发的(大部分浏览器会对无效的证书发出警告);
该证书正确地验证了被访问的网站(如,访问时收到了给example.com而不是其它组织的证书);
或者互联网上相关的节点是值得信任的,或者用户相信本协议的加密层(TLS或SSL)不能被窃听者破坏。
目录
SSL/TLS,HTTPS
WIKI: 传输层安全协议(傳輸層安全協議)
WIKI: 超文本传输安全协议(超文本传输安全协议)
简单与交互,客户端证书
简单简单策略即传输只使用服务端证书+协商加密。一般来说,只要网络请求库支持TLS,就可以自动实现这个功能。
支付中除了资金敏感的接口以外,大部分都是这个策略。
具体请看接口说明中,关于是否需要证书的地方。
交互参考示意图(傳輸層安全協議#/media/File:SSL_handshake_with_two_way_authentication_with_certificates.svg)
交互策略,也叫双向证书。除了使用服务器证书,客户端也必须使用特定的证书,才能和服务器交换秘钥,完成握手。
支付中,退款,发红包,企业付款,撤销等接口,使用的是这个策略。
具体请看接口说明中,关于是否需要证书的地方。
支付支持的TLS版本
参见公众平台公告(?action=getannouncement&key=&version=11&lang=zh_CN)
支付要求TLSv1.0及以上的版本。
(公众平台和开放平台也是一样的版本要求)
支付的证书与有效期
参见: 支付安全规范(?chapter=4_3)
信任链,CA
HTTPS的安全性,还涉及一个归纳问题:
只要公钥能解密,那么信息就是安全的
即逆推还要满足:
公钥必须是安全的
要证明公钥是安全的,使用的是背书的方式,即由另一个证书来保证这个证书的有效性。
那么最基础的那个证书就叫根证书。
一般来说,根证书是跟着ssl库一起分发的。更新ssl库就可以获得最新可信任的根证书。
在没有办法更新的情况下,支付的证书的根证书,也打包在压缩包里,可以选择导入(即手动信任根证书)。
域名与证书
证书和域名是强相关的。
这是由于互联网请求会有钓鱼问题。也就是公钥是安全的,加密也是安全的,但是请求目标却是假的。
https库在连接目标的时候,会验证目标的证书和本地请求的域名是否一致。
所以使用https请求的时候,是无法使用ip地址请求目标的。
解决这个问题的方法一般是在hosts当中给这个ip绑定一个域名。或者设置本地请求的时候不要验证此项。
测试网络设置
curl -k -d "@add_merchant.txt" --key "apiclient_key.pem" --cert "apiclient_cert.pem" ?action=add代理设置
为https请求设置代理非常复杂,主要是由于代理本身相当于是中间人的角色。
代理本身是分层的,通常的代理叫http代理,是在http协议层进行代理和转发。也就是说像这样:
client<--http(s)--> proxy <--http(s)--> server
对于简单策略的https,这样做问题不大,因为对服务器而言,代理就相当于客户端,实际客户端不可见。而代理和实际客户端之间可以选择http请求,这样虽然客户端想请求服务器,实际请求的却是代理,不会发生域名不一致的错误。
但是对于交互策略的https就会产生问题:实际报文到服务器的时候,必须已经被加密。但是如果是实际客户端加密,proxy就无法工作。所以客户端的证书只能部署在代理上,缺点会很明显:
证书安全多了个地方需要维护,而且暴露在外网。
如果涉及多个客户端证书(支付内即涉及多个商户号),代理上需要复杂的切换方案,比如多个代理地址。
这个时候有个比较少见的代理可以解决这个问题,即tcp代理。也就是tcp端口转发,还有地方会叫反向代理。
tcp代理不需要关注http包内容,不存在拆包。所以ssl加密可以由客户端完成。也就解决了上面的两个缺点:
证书放在实际客户端。
客户端代码即可以控制证书切换。
但是tcp代理确实相关文档较少,尤其是关于高性能要求环境下如何动态伸缩的指导较少。
http proxy
apache/nginxnginx的proxy文档:ngx_http_proxy_module()
squidssl bump()
tcp proxy
我实现的支付专用tcp proxy,相当于是个demo: https://github.com/btbxbob/wxpay-reverse-proxy
nginx的tcp proxy扩展,注意需要重新编译nginx: