常见问题

更新时间:2024.11.29

我们在【商户平台】->【自助服务】中设立了API证书及密钥 专区,包括了商户证书如何升级,申请,下载等问题的解答。下面是商户技术人员可能关心的一些问题。

什么是私钥?什么是证书?

数字签名通常定义了两种运算: 签名和验签。发送者用自己的私钥对消息的哈希值进行签名,接收者用对方的公钥进行验签。因此,在使用数字签名时,需要通信的双方都要事先生成公钥、私钥,并且完成双方的公钥交换。其中,私钥是只能由拥有者使用的不公开密钥,公钥是可以公开的密钥。

由于公钥本身并不含有拥有者的身份信息,使用时无法确认它是真实有效的。所以需要证书认证机构(简称 CA)在核实公钥拥有者的信息后,将公钥拥有者的身份信息(如商户号、公司名称等),公钥、签发者信息、有效期以及扩展信息等进行签名,制作成“证书”。

如何获取API证书?

什么是商户API证书?什么是微信支付平台证书?

  • “商户API证书”包含商户的商户号、公司名称、公钥信息的证书。商户可登录商户平台申请。

  • “微信支付平台证书”包含微信支付平台标识、公钥信息的证书。商户可通过调用下载平台证书接口或使用平台证书下载工具,获取当前可用的微信支付平台证书。

商户在调用 API 时用自身的私钥签名,微信支付使用商户API证书中的公钥来验签。

微信支付在响应的报文中使用自身的私钥签名,商户使用微信支付平台证书中的公钥来验签。

什么是证书序列号

每个证书都有一个由CA颁发的唯一编号,即证书序列号。

如何查看商户API证书序列号?

登录商户平台【API安全】->【API证书】->【查看证书】,可查看商户API证书序列号。

商户API证书和微信支付平台证书均可以使用第三方的证书解析工具,查看证书内容。或者使用openssl命令行工具查看证书序列号。

1$ openssl x509 -in 1900009191_20180326_cert.pem -noout -serial
2serial=1DDE55AD98ED71D6EDD4A4A16996DE7B47773A8C

如何在程序中加载证书

推荐使用微信支付提供的SDK。你也可以查看下列编程语言的示例代码。

JAVA:

1/**
2 * 获取证书。
3 *
4 * @param filename 证书文件路径  (required)
5 * @return X509证书
6 */
7public static X509Certificate getCertificate(String filename) throws IOException {
8    InputStream fis = new FileInputStream(filename);
9    BufferedInputStream bis = new BufferedInputStream(fis);
10    try {
11        CertificateFactory cf = CertificateFactory.getInstance("X509");
12        X509Certificate cert = (X509Certificate) cf.generateCertificate(bis);
13        cert.checkValidity();
14        return cert;
15    } catch (CertificateExpiredException e) {
16        throw new RuntimeException("证书已过期", e);
17    } catch (CertificateNotYetValidException e) {
18        throw new RuntimeException("证书尚未生效", e);
19    } catch (CertificateException e) {
20        throw new RuntimeException("无效的证书文件", e);
21    } finally {
22        bis.close();
23    }
24}

PHP:

1/**
2* Read certificate from file
3*
4* @param string    $filepath     PEM encoded X.509 certificate file path
5* 
6* @return resource|bool  X.509 certificate resource identifier on success or FALSE on failure
7*/
8public static function getCertificate($filepath) {
9    return openssl_x509_read(file_get_contents($filepath));}

为什么微信支付平台证书下载接口返回的证书需要加密?

主要是为了防御“中间人攻击”。

由于验证应答报文的签名和加密敏感信息时,必须使用到微信支付平台证书。微信支付平台证书是商户认证微信支付身份时最关键的要素。因此,要通过签名和加密等多重机制来保障商户获取到的微信支付平台证书没有被“中间人”篡改。

商户在调用下载接口获取微信支付平台证书时,应进行以下四步操作,以保证证书的真实性:

  • 使用与平台共享的对称密钥,解密报文中的证书(必须)

  • 通过解密得到的证书,来验证报文的签名(必须)

  • 使用证书查看工具,核对证书的颁发者为Tenpay.com Root CA。详见如何区分API证书的类型?(强烈推荐)

  • 通过证书信任链验证微信支付平台证书(强烈推荐)

如何通过证书信任链验证平台证书?

下面介绍如何使用openssl工具,通过证书信任链验证微信支付平台证书。

首先,从微信支付商户平台下载微信支付平台证书信任链 CertTrustChain.p7b ,并将它转换为pem证书格式。

1openssl pkcs7 -print_certs -in CertTrustChain.p7b -inform der -out CertTrustChain.pem

然后,-CAfile file指定受信任的证书,验证下载的微信支付平台证书

1openssl verify -verbose -CAfile ./CertTrustChain.pem ./WeChatPayPlatform.pem

为什么报错“HTTP header缺少微信支付平台证书序列号(Wechatpay-Serial)”?

商户上送敏感信息时使用了微信支付平台公钥加密。为了能使用正确的密钥解密,微信支付要求商户在请求的HTTP头部中包括证书序列号,以声明加密所用的密钥对和微信支付平台证书。详见这里的说明。