PAYATHON 2026

H5支付宝支付中的商户私钥和支付宝公钥如何配置?

支付阿杰

明确结论

H5 支付是支付宝 alipay.trade.wap.pay 接口的一种使用场景,密钥配置规则与支付宝开放平台的其他接口一致:

  • 商户私钥:由商户自行生成,用于请求签名,必须与上传到支付宝开放平台的”应用公钥”配对。
  • 原始格式 RSA 私钥:通常是密钥工具生成的 PKCS#1 私钥。它能否直接填写到”商户私钥”配置项,取决于所用 SDK 或支付插件要求 PKCS#1 还是 PKCS#8 格式。
  • 支付宝公钥:为应用配置”应用公钥”后,由支付宝开放平台提供,用于验证支付宝响应数据和异步通知的签名。它既不是本地生成的应用公钥,也不是商户私钥对应的公钥。

常见错误包括把”应用公钥”填入”支付宝公钥”字段,或者把带有头尾标记、换行和空格的私钥直接复制到只接受纯字符串的配置项中。

三种密钥分别是什么

密钥之间的关系可以简单理解为:

商户私钥  ──生成签名──> 支付宝验证商户请求
支付宝公钥 ──验证签名──> 商户验证支付宝通知和响应

商户在本地生成一对密钥:

商户私钥(也称应用私钥)
应用公钥

具体用法如下:

  • 商户私钥只保存在商户服务器上,不能上传、公开或发送给他人。
  • 应用公钥需要配置到支付宝开放平台。
  • 应用公钥配置完成后,平台会显示对应的支付宝公钥。
  • 商户需要把支付宝公钥复制到自己的系统中。

本地密钥工具生成的公钥通常是”应用公钥”,不能直接作为”支付宝公钥”使用。

正确配置步骤

1. 确认应用和签名模式

进入支付宝开放平台,找到实际用于 H5 支付的应用,确认以下信息:

  • app_id 与商户系统中的配置一致;
  • 接口加签使用普通公钥模式还是证书模式;
  • 签名算法通常为 RSA2,对应 SHA256WithRSA。

密钥必须属于当前 app_id。测试应用、沙箱应用和正式应用的密钥不能混用。

2. 保存商户私钥

使用支付宝密钥工具生成密钥时,一般会得到应用私钥和应用公钥。应用私钥就是商户用于签名的私钥。

常见的私钥格式如下。

PKCS#1:

-----BEGIN RSA PRIVATE KEY-----
MIIE...
-----END RSA PRIVATE KEY-----

PKCS#8:

-----BEGIN PRIVATE KEY-----
MIIE...
-----END PRIVATE KEY-----

有些管理后台要求填写完整的 PEM 内容,包括头尾标记和换行;有些插件只接受中间的 Base64 字符串。具体格式应以当前 SDK 或插件的字段说明为准,不能只根据”商户私钥”这个字段名称判断。

如果配置项要求填写”纯私钥字符串”,需要删除:

-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----

或者:

-----BEGIN PRIVATE KEY-----
-----END PRIVATE KEY-----

还要去掉换行、空格和不可见字符,只保留中间的 Base64 内容。

3. 上传应用公钥

把本地生成的”应用公钥”配置到支付宝开放平台对应应用的接口加签设置中。

公钥通常采用以下格式:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqh...
-----END PUBLIC KEY-----

如果平台要求粘贴纯字符串,也只需提交中间的 Base64 内容。不要把商户私钥上传到开放平台。

4. 获取支付宝公钥

应用公钥配置成功后,在该应用的接口加签配置页面查看并复制”支付宝公钥”。

需要注意:

应用公钥 ≠ 支付宝公钥

页面上的名称必须明确显示为”支付宝公钥”。不要从本地密钥工具中寻找支付宝公钥,也不要把本地生成的公钥再次填入商户系统的”支付宝公钥”字段。

5. 填入商户系统

使用普通公钥模式时,各配置项通常对应以下内容:

配置项应填写内容
app_id支付宝开放平台中的应用 ID
商户私钥、应用私钥或 merchant_private_key本地生成的私钥
支付宝公钥或 alipay_public_key开放平台显示的支付宝公钥
sign_type通常为 RSA2
charset通常为 UTF-8
notify_url可从公网访问的异步通知地址

配置示例

不同 SDK 对私钥格式的要求可能不同。下面是常见的”纯 Base64 字符串”配置方式:

$config = [
    'app_id' => '2021000000000000',
    'merchant_private_key' => 'MIIEvQIBADANBgkqhkiG9w0BAQEFAASC...',
    'alipay_public_key' => 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...',
    'sign_type' => 'RSA2',
    'charset' => 'UTF-8',
];

如果 SDK 要求使用 PEM 格式,则需要保留头尾标记和换行:

$merchantPrivateKey = <<<'PEM'
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASC...
-----END PRIVATE KEY-----
PEM;

$alipayPublicKey = <<<'PEM'
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...
-----END PUBLIC KEY-----
PEM;

不要把真实密钥直接写入可公开访问的代码仓库。可以从环境变量或受权限保护的配置文件中读取:

$merchantPrivateKey = getenv('ALIPAY_MERCHANT_PRIVATE_KEY');
$alipayPublicKey = getenv('ALIPAY_PUBLIC_KEY');

如何检查私钥格式

可以使用 OpenSSL 判断私钥格式,并检查内容是否完整。

检查 PKCS#1 RSA 私钥:

openssl rsa -in merchant_private_key.pem -check -noout

检查 PKCS#8 私钥:

openssl pkey -in merchant_private_key.pem -check -noout

从私钥导出对应的公钥:

openssl pkey -in merchant_private_key.pem -pubout -out derived_public_key.pem

导出的公钥应与配置到支付宝开放平台的应用公钥一致。如果两者不匹配,说明商户私钥和应用公钥不属于同一密钥对,签名验证一定会失败。

把 PKCS#1 私钥转换为未加密的 PKCS#8 格式,可以使用:

openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem \
  -outform PEM -nocrypt -out private_key_pkcs8.pem

转换不会改变密钥对本身。操作前应备份原文件,并严格限制私钥文件的访问权限。

复制后立即报错的常见原因

私钥格式不符合插件要求

例如,插件要求 PKCS#8,实际填写的私钥却以以下内容开头:

-----BEGIN RSA PRIVATE KEY-----

这种情况需要按照插件文档转换私钥格式,不能只删除头尾标记。

包含多余字符

从网页或编辑器复制密钥时,可能会带入以下内容:

  • 空格或空行;
  • 中文引号;
  • 全角字符;
  • HTML 标签;
  • 不可见字符;
  • \n 形式的字面字符串。

如果配置项要求纯字符串,内容中应只有 Base64 字符,通常包括字母、数字、+、/,末尾还可能有 =。

把应用公钥当成支付宝公钥

这种错误不一定会在保存配置时触发格式提示,但验证支付宝回调时通常会出现 sign check fail 或验签失败。

密钥与应用不对应

即使密钥格式正确,如果商户私钥对应的应用公钥没有配置到当前 app_id,调用接口时仍会提示签名错误。

RSA 与 RSA2 不一致

配置为 RSA2 时,签名和验签都应使用 SHA256WithRSA。不能一侧使用 RSA,另一侧使用 RSA2。

普通公钥模式和证书模式混用

如果开放平台使用证书模式,系统通常需要配置:

  • 应用公钥证书;
  • 支付宝公钥证书;
  • 支付宝根证书。

这种情况下,不能只填写一个”支付宝公钥”字符串。反过来,普通公钥模式也不应填写证书序列号或证书文件内容。

排查建议

可以先根据报错出现的阶段缩小范围:

  • 保存配置时立即报错:先检查字段格式、PKCS#1 或 PKCS#8 格式、头尾标记和换行。
  • 调用支付接口时提示签名错误:检查商户私钥、应用公钥、app_id 和 sign_type 是否对应。
  • 支付成功,但异步通知验签失败:检查是否误用了应用公钥,以及验签时使用的是否为支付宝公钥。
  • 只有正式环境或沙箱环境失败:检查是否混用了两个环境的应用 ID 和密钥。

不要在日志、截图或排错信息中展示完整的商户私钥。如果私钥已经泄露,应重新生成密钥对,并在支付宝开放平台更新应用公钥。

备注:内容仅供参考。