微信支付HTTPS服务器证书验证指引

背景介绍

微信支付使用HTTPS来保证通信安全, 在HTTPS服务器上部署了由权威机构签发的证书, 用于证明微信支付平台的真实身份。

商户与微信支付服务器通信前,商户需要往客户端的操作系统或者执行环境中部署权威机构的根CA证书,以便在调用微信支付API过程中, 验证服务器及域名的真实合法性。

因微信支付HTTPS服务器证书的根CA证书将于2018年8月23日到期失效,微信支付计划于2018年5月29日, 更换服务器证书。若你的服务器上没有部署新的根CA证书,将可能导致你的下单、退款等功能无法正常使用。

新的服务器证书由权威机构(DigiCert) 签发,部分操作系统和执行环境中已经内置了该根CA证书。 为了提升兼容性, 微信支付的服务器上部署了DigiCert的交叉证书, 所以客户端执行环境中包含以下两个根CA中的任意一个即可。

DigiCert根CA证书兼容性列表如下:

权威机构根CA证书

证书序列号

证书有效期

Windows兼容

Java兼容

证书下载

DigiCert Global Root CA

08:3b:e0:56:90:42:46:b1:a1:75:6a:c9:59:91:c7:4a

2006.11.10 - 2031.11.10

Windows 7+

1.6.05及以上

PEM格式

DER格式

Baltimore CyberTrust Root CA

02:00:00:b9

2000.5.13 - 2025.5.13

Windows XP及以上

1.4.2及以上

PEM格式

DER格式

常见问题

Q1:什么是微信支付HTTPS服务器证书?

A:微信支付HTTPS服务器证书是由权威机构颁发的证书。商户调用微信支付API时,能通过该证书来认证微信支付的身份。

Q2:什么是根证书?

A:权威机构用它的“私钥”来颁发服务器证书。 与“私钥”相对应的是“公钥”,“公钥”被用来认证服务器证书的真实性。权威机构的公钥会被制作成证书,简称“根证书”。

Q3:根证书和API证书是同一个吗?

A:不是,两者没有关系。

“根证书”是用来校验微信支付的域名及服务器的真实性, 通常内置在操作系统或者执行环境(如JRE等)中。

“API证书”是用来证实商户身份的,通常在调用微信支付安全级别较高的接口(如:退款、企业红包、企业付款等)时,才会使用到API证书。

Q4:微信支付为什么要更换服务器证书?

A:根证书存在有效期,根证书到期后无法继续被用来校验服务器证书。

因此微信支付申请了新的服务器证书。避免在根过期后商户调用微信支付API时出现问题,新的证书计划于2018年5月29日更换。

Q5:微信支付更换服务器证书需要商户配合做哪些事情?

A:仅需开发人员在调用微信支付API的服务器上,确认是否已部署用于验证微信支付新服务器证书的受信根证书。

如未部署,请按指引自行安装证书,不产生任何费用。

此外,商户使用的其它https证书不需要更换或者升级。

Q6:如果不验证,会影响下单/退款等功能吗?

A:大部分情况下,即使不验证根证书也不会影响下单、退款等功能。为了避免商户服务器上没有对应根证书的情况,建议商户仍然按照指引进行验证。

Q7:微信支付更换证书前,开发人员可以提前安装根CA证书吗?还是要微信支付更换后,再安装根CA证书?

A:需要提前安装。提前安装根证书不会影响商户正在使用的功能。

验证证书

由于SSL/TLS协议有多种实现版本(OpenSSL, NSS, GnuTLS, JSSE, Schannel等),且在不同实现版本和操作系统中管理权威机构根CA证书的策略不一样,应用程序使用SSL/TLS的方法也存在差异。

为了确保微信支付更换服务证书后,不影响商户的正常交易。下面提供了两种方式供商户提前验证客户端是否支持了DigiCert的证书。

如你的验证结果为无影响,可忽略安装证书部分的内容。

方式一:调用微信支付沙箱环境的API接口验证

微信支付已经将新的服务器证书部署到了沙箱域名(apitest.mch.weixin.qq.com), 由于服务器证书是支持多域名的,API域名(api.mch.weixin.qq.com)与沙箱域名(apitest.mch.weixin.qq.com)使用的是同一张证书。如果使用沙箱环境的接口能调用成功,通常表明客户端支持微信支付新的服务器证书。

API接口调用说明:

请求Url https://apitest.mch.weixin.qq.com/sandboxnew/pay/getsignkey
是否需要证书
请求方式 POST
请求格式 XML

请求参数:

字段名 字段 必填 示例值 类型 说明
商户号 mch_id 1305638280 String(32) 微信支付分配的微信商户号
随机字符串 nonce_str 5K8264ILTKCH16CQ2502SI8ZNMTM67VS String(32) 随机字符串,不长于32位
签名 sign 5K8264ILTKCH16CQ2502SI8ZNMTM67VS String(32) 签名结果,详见签名生成算法

返回参数:

字段名 字段 必填 示例值 类型 说明
返回状态码 return_code SUCCESS String(16) SUCCESS/FAIL 
返回信息 return_msg 签名失败 String(128) 返回信息,如非空,为错误原因 ,签名失败 ,参数格式校验错误

以下字段在return_code 为SUCCESS的时有返回。

字段名 字段 必填 示例值 类型 说明
商户号 mch_id 1305638280 String(32) 微信支付分配的微信商户号
沙箱密钥 sandbox_signkey 013467007045764 String(32) 返回的沙箱密钥

当返回结果return_code为“SUCCESS”,说明当前客服端已支持DigCert证书,反之则需要根据安装证书部分的指引,升级证书。

方式二:绑定HOST,请求已部署新证书的微信支付API服务器

注意:验收完成后,请及时恢复服务器上的host配置,微信支付服务器证书更新完成后,此处使用的IP会被关停。

商户可以根据不同的网络运营商, 为域名 api.mch.weixin.qq.com 配置以下HOST:

网络运营商

绑定IP

端口

电信

113.96.240.139

443

联通

157.255.180.139

443

其它(移动, 长城等)

121.51.30.139

443

HOST环境可以访问的接口与正式环境完全一致,且真实生效, 商户验证前, 务必评估对业务的影响。 如果未配置以上HOST的话, 在2018年5月31日前,访问api.mch.weixin.qq.com时, 服务器依然返回老的GeoTrust证书。

如果可以正常访问api.mch.weixin.qq.com域名下的统一下单、查询订单等接口,说明客户端支持了DigCert证书,反之则需要根据安装证书部分的指引,升级证书。

注意事项:

◆ 建议商户在使用方式A验证后, 再使用方式B验证, 以确保交易不受影响

◆ 建议不要忽略服务器证书校验的错误, 避免受到中间人攻击

◆ 请确保验证环境和正式环境一致,需要使用相同的操作系统、开发语言、执行环境、SSL\TLS库等

安装证书

如果你的服务器上没有内置DigiCert的根CA证书, 采用上面两种方式验证的过程中, 可能会碰到问题。需要你主动往操作系统或者执行环境的证书信任列表中,添加DigiCert的根证书。

为了提升兼容性, 微信支付的服务器上部署了DigiCert的交叉证书. 客户端的执行环境中需要安装(Baltimore CyberTrust Root.crt DigiCert Global Root CA.crt)中的任意一个, 即可。

DigiCert根CA证书兼容性列表如下:

权威机构根CA证书

证书序列号

证书有效期

Windows兼容

Java兼容

证书下载

DigiCert Global Root CA

08:3b:e0:56:90:42:46:b1:a1:75:6a:c9:59:91:c7:4a

2006.11.10 - 2031.11.10

Windows 7+

1.6.05及以上

PEM格式

DER格式

Baltimore CyberTrust Root CA

02:00:00:b9

2000.5.13 - 2025.5.13

Windows XP及以上

1.4.2及以上

PEM格式

DER格式

下面针对几种主流的开发语言, 介绍如何安装新的根证书:

1.JAVA

Java使用JSSE包中的信任管理器来校验远端服务器的证书是否合法, TrustStore文件中保存了根证书信任列表. JRE 1.4.2及以上版本自带的TrustStore文件(lib/security/cacerts)中均内置了DigiCert的根证书。

◆ 如果你使用的JRE版本为1.4.2及以上, 且使用默认的TrustStore文件(lib/security/cacerts), 通常不需要做额外配置, 就能支持新的服务器证书。

◆ 如果你使用的JRE版本低于1.4.2 , 或者在系统属性javax.net.ssl.trustStore中指定了自定义的TrustStore, 那么需要使用JAVA自带的证书管理工具 Keytool导入DigiCert的根证书(Keytool需要在java安装目录下的lib/security/文件夹中执行)。 具体的命令为:

操作系统

操作

命令行

windows

查看

keytool.exe -list -keystore  cacerts  -storepass changeit

(digicert证书的别名为: digicertglobalrootca 或者 baltimorecybertrustca)

新增

keytool.exe -importcert -keystore cacerts -storepass changeit -noprompt  -file ./DigiCert_Global_Root_CA.der -alias " digicertglobalrootca"

(证书格式需要为der)

linux

查看

keytool -list -keystore  cacerts  -storepass changeit

(digicert证书的别名为: digicertglobalrootca 或者 baltimorecybertrustca)

新增

keytool -importcert -keystore cacerts -storepass changeit -noprompt  -file ./DigiCert_Global_Root_CA.der -alias " digicertglobalrootca

(证书格式需要为der)

2.C\C++

使用C++开发的应用程序, 通常使用libcurl库发起https请求, libcurl支持多种SSL\TLS引擎, 如 OpenSSL, SChanel, NSS等。

更详细的内容,可参考:https://curl.haxx.se/docs/ssl-compared.html

◆使用OpenSSL时, 参考如下操作:

步骤一: 查看openssl根证书信任文件路径.  执行命令行 openssl version –a ,输出结果中的 OPENSSLDIR就是根证书信任文件路径

$ openssl version -a

OpenSSL 1.0.1e-fips 11 Feb 2013

built on: Tue Mar 24 14:14:19 CST 2015

platform: linux-x86_64

options:  bn(64,64) md2(int) rc4(16x,int) des(idx,cisc,16,int) idea(int) blowfish(idx)

compiler: gcc -fPIC -DOPENSSL_PIC -DZLIB -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DKRB5_MIT -m64 -DL_ENDIAN -DTERMIO -Wall -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -Wa,--noexecstack -DPURIFY -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM

OPENSSLDIR: "/etc/pki/tls"

engines:  rdrand dynamic

步骤二: 按照验证证书的方式二配置host,然后使用以下命令行, 确认操作系统内置的根证书中, 是否支持DigiCert证书

$ openssl s_client -connect api.mch.weixin.qq.com:443  -verify_return_error  -CApath $OPENSSLDIR
或者
$ openssl s_client -connect api.mch.weixin.qq.com:443  -verify_return_error

正常的输出为:

depth=3 C = IE, O = Baltimore, OU = CyberTrust, CN = Baltimore CyberTrust Root

verify return:1

depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA

verify return:1

depth=1 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = GeoTrust RSA CA 2018

verify return:1

depth=0 C = CN, L = Shenzhen, O = Tencent Technology (Shenzhen) Company Limited, OU = R&D, CN = payapp.weixin.qq.com

verify return:1

CONNECTED(00000003)

---

Certificate chain

0 s:/C=CN/L=Shenzhen/O=Tencent Technology (Shenzhen) Company Limited/OU=R&D/CN=payapp.weixin.qq.com

i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=GeoTrust RSA CA 2018

1 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=GeoTrust RSA CA 2018

i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root CA

2 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root CA

i:/C=IE/O=Baltimore/OU=CyberTrust/CN=Baltimore CyberTrust Root

缺少DigiCert根证书时, 可能输出的错误信息为:

depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA

verify error:num=20:unable to get local issuer certificate

verify return:0

CONNECTED(00000003)

---

步骤三: 安装根证书。几种常见的linux发行版本的操作命令如下:

操作系统

操作

命令行

Ubuntu, Debian

查看根证书

确认操作系统上,是否存在以下文件:

  1. /etc/ssl/certs/DigiCert_Global_Root_CA.pem
  2. /etc/ssl/certs/Baltimore_CyberTrust_Root.pem

安装根证书

  1. 复制根证书文件到 /usr/local/share/ca-certificates/
  2. 安装根证书:  sudo update-ca-certificates

(更多的命令行参数及说明, 请查看: man update-ca-certificates)

CentOs,

Red Hat Enterprise Linux

查看根证书

确认/etc/pki/tls/certs/ca-bundle.crt文件中, 是否存在以下内容:

  1. DigiCert Global Root CA

Serial Number:  08:3b:e0:56:90:42:46:b1:a1:75:6a:c9:59:91:c7:4a

  1. Baltimore CyberTrust Root

Serial Number: 0x20000b9

安装根证书

  1. 安装根证书管理包软件:  yum install ca-certificates
  2. 打开根证书动态配置开关:  update-ca-trust force-enable
  3. 将DigiCert的根证书文件复制到: /etc/pki/ca-trust/source/anchors/
  4. 安装根证书:  update-ca-trust extract

(更多的命令行参数及说明, 请查看: man update-ca-trust)

◆ 使用Schannel时, 参考如下操作:

Windows系统上的libcurl使用的TLS引擎是Schannel, 根证书的导入可以参考C#章节。

3.C#

在windows服务器上的C#开发语言或者, 通常使系统自带Schannel(别名: Secure Channel 或者 WinSSL)发起HTTPS请求, 权威机构的根证书由Windows操作系统集中管理。

可通过以下步骤来确认操作系统中是否内置了根证书 :

步骤一: 打开mmc(在搜索程序中输入mmc,然后回车)进入如下界面:

微信支付HTTPS服务器证书验证指引

步骤二: 在”文件”中选择 “添加/删除管理单元”:

微信支付HTTPS服务器证书验证指引

步骤三: 在“添加/删除管理单元”中选择”证书”, 双击后选择 “计算机账户”和”本地计算机”:

微信支付HTTPS服务器证书验证指引

选择证书, 点击添加:

微信支付HTTPS服务器证书验证指引

微信支付HTTPS服务器证书验证指引

步骤四: 点击完成后, 可以看到如下界面. 右键单击”受信任的根证书颁发机构”:

微信支付HTTPS服务器证书验证指引

步骤五: 选中查找证书, 搜索”证书序列号”为“08 3b e0 56 90 42 46 b1 a1 75 6a c9 59 91 c7 4a” 或者” 02 00 00 b9” 如果有结果输出, 则表明操作系统中已经内置了DigiCert的根CA证书

微信支付HTTPS服务器证书验证指引

如果操作系统中, 没有内置DigiCert根CA证书的话. 可以通过以下步骤安装:

步骤一:双击根证书文件,“安装证书”:

微信支付HTTPS服务器证书验证指引

步骤二:在弹出证书导入向导中,如右图所示, 点击下一步:

微信支付HTTPS服务器证书验证指引

步骤三:在“选择证书存储”对话框中选择“受信任的根证书颁发机构”,点击确定

微信支付HTTPS服务器证书验证指引

步骤四:点击“完成”,系统提示”导入成功”。导入成功后, 可以按照前面介绍方法确认系统中DigiCert根证书

微信支付HTTPS服务器证书验证指引

4.其它语言

GO语言: 
  1. 请检查你的代码(特别是退款、企业红包及企业付款等需要双向认证的接口)中是否指定了crypto/tls包中的 RootCAs 配置项。 (可参考: https://golang.org/pkg/crypto/tls/ ) 
  2. 如果没有指定根证书文件,请按指引中提供的验证方式,确认是否支持微信支付新的服务器证书 
  3. 如果指定了根证书文件, 请务必删除相关代码,然后验证现有功能是否正常, 再验证是否支持微信支付新的服务器证书。
 备注: GO语言中校验服务器证书的规则为:
 a) 缺省情况下, 用系统自带的根证书。
 b) 如果商户指定了根ca的话, 就用商户指定的。
 c) 当商户指定的根CA证书与服务器证书不匹配时,接口调用会失败, 错误提示为 "x509: certificate signed by unknown authority" 

其他请参考对应的TLS/SSL库相关手册。

上一篇:V3 微信支付-预支付C#


下一篇:java学习笔记09--反射机制