1. 背景介绍
微信开放平台使用 HTTPS 协议来确保通信的安全性。在开发者调用微信开放平台 API 的过程中,需要在其操作系统或执行环境(如 JRE 等)中部署权威机构的根证书,以验证微信开放平台服务器证书的真实性,进而验证微信服务器及其域名的真实性。
受 Mozilla 信任库的最新根证书信任策略影响(全球所有 CA 的可信根证书需每15年更换一次,超过此时间的可信根将逐渐失去 Mozilla 的信任),DigiCert 将逐步停止使用旧的根证书体系(G1)来颁发 TLS/SSL 证书,转而采用新的根证书体系(G2)。
当前微信开放平台服务器证书的颁发根 CA 是 Digicert Global Root CA (G1),微信开放平台计划于 2024年10月22日 0:00 开始,逐步启用采用 DigiCert Global Root G2 根 CA 颁发的新服务器证书,开发者应仔细阅读本指引,并完成相关验证和修正,以免影响正常服务。
注意:
1)所有通过 api.weixin.qq.com 调用的 API 都可能受影响,开发者需要在 2024年10月22日 0:00 之前参考指引完成相关验证和修正。
2)大多数操作系统和执行环境都默认内置了 DigiCert Global Root G2 根证书,因此大多数系统无需改动即可兼容新服务器证书。但如果开发者的服务器未内置 G2 根证书,或程序代码指定使用旧的 G1 根证书,则会受到影响,将出现服务中断的问题。我们建议及时移除指定旧根证书代码,采用系统自带的信任库进行验证,同时确保系统内置有 DigiCert Global Root G2 根证书。
3)新的 G2 根体系采用更高安全性的 SHA256 签名算法,且依然兼容当前主流的操作系统和移动设备,主流环境兼容情况如下:
对应的根证书文件请参考:
Baltimore CyberTrust Root:Download PEM、Download DER/CET
Digicert Global Root CA:Download PEM、 Download DER/CRT
Digicert Global Root G2:Download PEM、 Download DER/CRT
2. 开发须知
开发者需确认与微信开放平台对接的服务器系统可兼容新的服务器证书,并参考“验证指引”章节的方法,在 2024年10月22日 0:00 之前完成验证:
• 如果验证结果正常,开发者不需要做其它任何事情
• 如果验证结果异常,开发者需要修改相关的系统实现或配置,且需最晚于 2024年10月22日 0:00 之前前完成修正,否则开发者的业务系统与微信开放平台系统之间将不能正常进行 HTTPS 通讯,将影响业务正常运行。
开发者在验证和修正过程中遇到问题,可在小程序专区发帖咨询,我们会有专人进行解答回复。
3. 验证指引
验证方式:绑定 host,请求已部署新证书的微信开放平台服务器
开发者可通过修改操作系统的 hosts 文件来绑定 IP,例如,可在 hosts 文件中新增一行如下内容,实现将域名"api.weixin.qq.com"绑定到新证书环境:
81.69.216.137 api.weixin.qq.com
在 Linux 系统下,hosts文件的完整路径为"/etc/hosts",在Windows系统下,hosts 文件的完整路径为"C:\Windows\System32\drivers\etc\hosts"。
注意:
1、host 环境可以访问的接口与正式环境完全一致,且真实生效,被视为生产正式业务。在验证之前,请充分评估对贵司业务系统以及业务的影响
2、验证完成后,请及时恢复服务器上的 host 配置,微信开放平台服务器证书更新完成后,此处使用的 IP 会被关停。
3、需要用和生产环境相同的操作系统、执行环境、开发语言及程序逻辑进行验证。使用 curl 等命令行工具验证成功,并不代表你的系统支持了新的服务器证书。
4、逐一验证所有正在调用的微信开放平台接口,如果均能正常使用,说明系统支持微信开放平台新的服务器证书。反之,则需要根据修正指引排查问题并修正。
4. 修正指引
大部分情况下,验证失败是以下两种情况导致的:
情况一:程序中指定了根证书,但是指定的根证书中仅包含了旧的 G1 根证书。
情况二:服务器上没有部署新的 G2 根证书。
可通过以下两个方案修正:
方案一:删除指定根证书的代码。当程序中不指定根证书时,会使用系统自带的根证书。绝大部分系统中已内置了新的 G2 根证书,所以删除指定根证书的代码,不会影响到你的现有业务。
方案二:更新根证书。往 truststore 或者根证书信任文件中追加新的 G2 根证书(注意:追加新的根证书时,需要保留老的G1根证书)。
推荐使用“方案一”来修正,该方案的兼容性更好。原因是:新的 G2 根证书将于 2029年4月15日不再被 Mozilla 信任,到时候同样要更换新的根证书。使用方案一修复,你的系统中很可能已内置了后续需更换使用的根证书,从而不受影响。如果使用方案二进行修复,在 2029年4月15日仍可能需安装新的根证书。
下面介绍各种开发语言可能碰到的问题及解决方法:
JAVA常见错误
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
可能原因: 代码中设置了 javax.net.ssl.trustStore 。 可以在代码中搜索关键字“trustStore” 或者 “TrustManager” 来确认
解决方法:
方法一、删除掉指定javax.net.ssl.trustStore
的代码
方法二、安装新的根证书, 往指定的trustStore 中添加新的根证书。操作命令:keytool -importcert -keystore cacerts -storepass changeit -noprompt -file ./DigiCertGlobalRootG2.crt -alias digicertglobalrootg2
C++常见错误
cURL error 60: SSL certificate: unable to get local issuer certificate.
CURLE_SSL_CACERT (60) peer certificate cannot be authenticated with known CA certificates.
可能原因: 代码中设置了CURLOPT_CAINFO
。 可以在代码中搜索关键字“CURLOPT_CAINFO”来确认
解决方法:
方法一、删除掉curl_easy_setopt(pCurl,CURLOPT_CAINFO,"./rootca.pem")
相关的代码
方法二、更新rootca.pem。用libcurl官网最新的 https://curl.haxx.se/ca/cacert.pem 替换即可
PHP常见错误
cURL error 60: SSL certificate: unable to get local issuer certificate.
CURLE_SSL_CACERT (60) peer certificate cannot be authenticated with known CA certificates.
可能原因:
使用libcurl时设置了CURLOPT_CAINFO
。可以在代码中搜索关键字“CURLOPT_CAINFO”来确认。
解决方法:
方法一、删除掉类似curl_setopt(pCurl, CURLOPT_CAINFO, "./rootca.pem");
的代码
方法二、更新rootca.pem。用libcurl官网最新的https://curl.haxx.se/ca/cacert.pem 替换即可
C#常见错误
RemoteCertificateValidationCallback 设置的回调函数返回 false
可能原因: 操作系统中没有新的根CA
解决方法: 安装新的根证书
Python常见错误
SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581)
可能原因: 代码中用 verify 指定了根证书文件。 可以在代码中搜索关键字“verify”来确认。类似的代码如:
response = requests.post(
"https://api.mch.weixin.qq.com/secapi/pay/refund",
verify="./rootca.pem",
……
);
解决方法:
方法一、删除verify参数
方法二、更新rootca.pem
。用libcurl官网最新的https://curl.haxx.se/ca/cacert.pem 替换即可
go常见错误
x509: certificate signed by unknown authority .
可能原因: 发起https时, 用 RootCAs指定了根证书文件。 可以在代码中搜索关键字 “RootCAs” 来确认。类似的代码如:
roots.AppendCertsFromPEM([]byte(rootPEM))
tr := &http.Transport{
TLSClientConfig: &tls.Config{RootCAs: roots},
}
client := &http.Client{Transport: tr}
解决方法:
方法一、删除配置项RootCAs
方法二、更新rootca.pem
。用libcurl官网最新的https://curl.haxx.se/ca/cacert.pem 替换即可
Ruby常见错误
SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
可能原因: 发起https时, 用ssl_ca_file
或者cert_store
指定了根证书文件。 可以在代码中搜索关键字“ssl_ca_file” 或者 “cert_store” 来确认。类似的代码如:
"https://api.mch.weixin.qq.com/secapi/pay/refund",
:ssl_client_cert => OpenSSL::X509::Certificate.new(File.read("./apiclient_cert.pem ")),
:ssl_client_key => OpenSSL::PKey::RSA.new(File.read("./apiclient_key.pem ")),
:ssl_ca_file => "./rootca.pem",
:verify_ssl=>OpenSSL::SSL::VERIFY_PEER).post(data);
或者
sock.cert_store.add_file('/usr/lib/ssl/certs/weixin/rootca.pem')
解决方法:
方法一、删除 ssl_ca_file
及 cert_store 指定的参数
方法二、更新rootca.pem。用libcurl官网最新的https://curl.haxx.se/ca/cacert.pem 替换即可
NodeJs常见错误
Caught exception: Error: CERT_UNTRUSTED
可能原因: 代码中用 ca 指定了根证书文件。 可以在代码中搜索关键字“ca” 或者 “rootca” 来确认。类似的代码如:
hostname: api.mch.weixin.qq.com ',
pfx: await readFile('./apiclient_cert.p12'),
ca: await readFile('./rootca.pem'),
};
const req = https.request(options, (res) => {
……
解决方法:
方法一、删除ca指定的参数
方法二、更新rootca.pem
。用libcurl官网最新的https://curl.haxx.se/ca/cacert.pem 替换即可
其它语言请参考对应的TLS/SSL库相关手册。
5. 常见问题
Q1:什么是服务器证书?
A:服务器证书通常又叫“SSL 证书”、“HTTPS 证书”,它由权威 CA 机构颁发,用于对网站进行身份鉴定,并使客户端与网站之间通过 TLS/SSL 协议建立起安全传输通道。微信开放平台的服务器证书是由权威机构 DigiCert 颁发,开发者调用微信开放平台 API 时,能通过该证书来认证微信服务器身份。
Q2:什么是根证书?
A:根证书是权威 CA 机构给自己颁发的证书,是信任链的起始点,是证书颁发机构(CA)与用户建立信任关系的基础。操作系统、浏览器、TLS/SSL 开发库通常随软件发行包预置其信任的权威机构的根证书。
Q3:微信开放平台为什么要更换服务器证书?
A:根证书存在有效期,根证书到期后无法继续被用来校验服务器证书。
因此,微信开放平台向权威机构(CA)申请了新的服务器证书。避免在老的根证书过期后,开发者调用微信开放平台 API 时出现问题。
Q4:微信开放平台更换服务器证书,需要开发者配合做哪些事情?
一、验证你的系统是否兼容微信开放平台新的服务器证书。
二、若支持的话,不需要做任何操作。若不支持,需要参考修正指引排查原因并修正。
注意:
a)开发者按指引进行验证或安装新的根证书, 不会产生任何费用。
b)开发者正在使用的其它 HTTPS 证书不需要更换或者升级。
Q5:开发者如何核实服务器上是否已内置了G2根证书?
A: 以 Linux 系统为例。Linux 系统信任根证书库的保存位置因发行版本不同而有所差异:Debian/Ubuntu:/etc/ssl/certs/ca-certificates.crt
CentOS/RHEL/Fedora/TencentOS:/etc/pki/tls/certs/ca-bundle.crt
开发者可以使用以下命令来核实系统是否已内置了G2根证书
grep "DigiCert Global Root" /etc/pki/tls/certs/ca-bundle.crt
# DigiCert Global Root CA
# DigiCert Global Root G2
备注:示例显示系统已内置了G1和G2根证书
Q6:微信开放平台更换证书前,可以提前安装根 CA 证书吗?
A: 必须提前安装,且建议在 2024年10月22日 0:00 之前提前安装。因为从 2024年10月22日 0:00开始,微信开放平台会在生产环境逐步灰度启用新服务器证书,以校验开发者的系统是否兼容新证书。微信开放平台在更换新证书的过程中,会同时使用新老两个服务器证书,开发者要能正常处理这种情况。因此,开发者的服务器上需要包含新老两个根证书。
Q7:开发者需在什么时候完成验证和修正?不验证会有什么影响?
A: 开发者应在 2024年10月22日 0:00 之前完成验证和修正。如果开发者侧系统的实现方式已能兼容新的服务器证书,那么不会影响业务;如果开发者侧系统的实现方式不能兼容新的服务器证书,那么会导致开发者的系统与微信开放平台的系统不能正常交互,影响业务。
Q8:如果开发者无法按时完成兼容性修正,在微信开放平台灰度新证书时遇到异常应如何处理?
A: 如果开发者的系统经验证是不能兼容新证书的,开发者应在 2024年10月22日 0:00 之前完成修正。如果无法按时完成修正,我们届时可提供仍使用旧证书的临时环境,开发者可通过 host 绑定 IP 的方式使用,以临时规避证书更换产生的影响。请务必在2024年10月22日 0:00 之前完成系统修正,并取消绑定临时环境IP,恢复以正常的方式对接微信开放平台的生产正式环境。
6. 特别提醒
1)为提前发现开发者“是否会受到证书更换的影响?”“有没有升级完根证书?”,微信开放平台将于 2024年10月22日 0:00 开始,把开发者的部分请求转发到部署了新证书的服务器上,并逐步提升灰度比例。当开发者不支持新的服务器证书时,会出现 SSL 相关的错误,通常情况下重试即可恢复。
2)根证书升级仅跟服务器和应用程序相关,与 APPID 没关系。只要在同一台服务器升级完成后,该服务器上使用的所有 APPID 都可以正常使用的。
3)如果你是通过代理服务器向微信开放平台发起请求,那么需要修改代理服务器的配置。
7. 联系我们
如果开发者在验证或者修正问题的过程中遇到困难,可在小程序专区发帖咨询,我们会有专人进行解答回复。
8. 附录
DigiCert 原文公告 :DigiCert root and intermediate CA certificate updates 2023
更换证书的文档:
https://developers.weixin.qq.com/community/develop/article/doc/0002025ca6c3a8c4d7d1afbaf6b013
使用的接口:获取用户信息
https://api.weixin.qq.com/sns/userinfo?access_token=xxxxx2xM&openid=xxxxxxxxxxxxxx,result:{"errcode":-1,"errmsg":"system error, rid: 66cd715a-508071c4-210374e9"}
响应的参数:{"errcode":-1,"errmsg":"system error, rid: 66cd715a-508071c4-210374e9"}
配置请求的host:
81.69.216.137 api.weixin.qq.com
将host 删除后,业务恢复正常
请问如何处理???
配置hosts后从2024-09-30 17:59:08开始调用https://api.weixin.qq.com/cgi-bin/component/api_component_token接口就返回system error, 最新返回system error rid: 670498ae-4968ce09-316bc641,官方看到麻烦回复一下, 谢谢
java环境检查是否存在证书
keytool -list -storepass changeit -keystore $JAVA_HOME/lib/security/cacerts -rfc | grep digicert
简单来说 近几年新装的服务器没影响
windows服务器杂看有没有g2证书?
我使用的是微信云托管服务器,是不是不需要做任何操作呢?
Linux服务器上执行
grep "DigiCert Global Root" /etc/pki/tls/certs/ca-bundle.crt
得到的结果如下所示:
# DigiCert Global Root CA # DigiCert Global Root G2 # DigiCert Global Root G3
是不是就没什么影响啊?
请问现在新证书环境的HOST还是这个吗?我这边用G1证书验证也通过了