支付宝开放平台需配置应用私钥、应用公钥、支付宝公钥三类密钥;php中rsa2签名须用pkcs#1格式私钥,通过openssl_pkey_get_private加载,验签时确保字符串拼接规范、公钥无隐藏字符、算法显式指定sha256。

支付宝开放平台密钥到底要配哪几个?
支付宝开放平台对接时,密钥不是“一个密钥走天下”,而是必须同时配置三类密钥:应用私钥(app_private_key)、应用公钥(app_public_key)、支付宝公钥(alipay_public_key)。少一个或配错位置,签名验证必然失败,常见报错如 INVALID_SIGNATURE 或 ILLEGAL_SIGN。
注意:应用私钥由你本地生成,绝不能上传给支付宝;你上传到开放平台的是对应的应用公钥;而支付宝公钥必须从开放平台「开发者中心 → 应用详情 → 开发信息」页面手动复制粘贴,不能用接口拉取,也不能复用旧应用的值。
PHP里怎么加载和使用RSA2密钥?
支付宝当前强制要求 RSA2(SHA256WithRSA)签名算法,PHP 7.1+ 原生 openssl 支持,但要注意密钥格式和加载方式:
-
app_private_key必须是 PKCS#1 格式(以-----BEGIN RSA PRIVATE KEY-----开头),若你用 OpenSSL 生成的是 PKCS#8(-----BEGIN PRIVATE KEY-----),需转换:openssl pkcs8 -in app_private_key.pem -nocrypt -out app_private_key_pkcs1.pem
- 加载时不要用
file_get_contents()直接塞进openssl_sign(),必须用openssl_pkey_get_private()解析,否则返回 false;同理,支付宝公钥要用openssl_pkey_get_public() - 签名示例关键片段:
$res = openssl_pkey_get_private($app_private_key);<br>openssl_sign($data, $sign, $res, OPENSSL_ALGO_SHA256);<br>$sign = base64_encode($sign);
为什么验签老失败?重点检查这三点
验签失败占密钥问题的 80% 以上,基本不是算法写错,而是数据预处理不对:
立即学习“PHP免费学习笔记(深入)”;
- 待验签字符串必须严格按支付宝文档拼接:所有参数按 key 字典序排序,只拼接 value 非空且非 sign 的字段,不urlencode(支付宝 SDK 内部已处理,你自己拼前别 urlencode)
-
alipay_public_key必须是纯文本(无换行、无空格、无 BOM),复制后建议用 hex 编辑器确认首尾没隐藏字符;常见错误是粘贴时带了\r\n或网页自动加的全角空格 - 验签函数必须用
OPENSSL_ALGO_SHA256,不能用OPENSSL_ALGO_SHA1—— 即使你选的是 RSA2,底层验签仍需显式指定 SHA256 算法
要不要用官方 SDK?还是自己封装?
支付宝官方 PHP SDK(alipay-easysdk)已全面替代老版 alipay-sdk-php,它内置密钥管理、自动签名/验签、HTTP 封装,适合新项目。但如果你已有稳定封装,不建议强行切换,因为:
- 老 SDK 已停止维护,但只要没升级到新版网关(
openapi.alipay.com)仍可运行;新 SDK 要求 PHP >= 7.2,且依赖guzzlehttp/guzzle - 自研封装更轻量,可控性强,但必须确保:
signType=RSA2、charset=utf-8、format=json这三个请求头/参数始终正确,漏一个就 400 或验签失败 - 生产环境务必关闭调试模式(
debug=false),否则 SDK 可能输出敏感密钥到日志
密钥本身不难配,难的是每一步都“刚好对”——格式、编码、顺序、算法、环境变量加载时机,任意一环差一点,整个链路就静默失败。











