Closed dcboy closed 3 months ago
同问
刚试到,只要在运行exec时加入appCertSn和alipayRootCertSn就可以了 但前题是你要找到证书的sn
@cheuk3 你好 请问 appCertSn 和 alipayRootCertSn 具体是放在哪个里面 放在公共参数里面吗?
@cheuk3 你好 请问 appCertSn 和 alipayRootCertSn 具体是放在哪个里面 放在公共参数里面吗?
給你參考
alipaySdk.exec("alipay.trade.pay", {
appCertSn: string,
alipayRootCertSn: string,
notifyUrl: string
bizContent: {
...
}
});
{ code: '40002', msg: 'Invalid Arguments', subCode: 'isv.app-cert-not-exist', subMsg: '应用公钥证书不存在' } 一直都是这个错误 烦死了额
應該是你的sn不對, 他找不到那証書
let publicdata = { charset: "UTF-8", method: "alipay.fund.trans.uni.transfer", timestamp: , version: "1.0", appCertSn: 'xxxx', alipayRootCertSn: '687b59f3d3b83462e1dfcf6', bizContent: biz_content };
const alipaySdk = new AlipaySdk({
appId: '',
privateKey: fs.readFileSync(think.ROOT_PATH + '//rsa_private_key.pem', 'ascii'),
keyType: "PKCS8",
});
我是用 c# sdk 搞出了sn 应该不会错吧
@cheuk3 可以加个qq 吗
我是用以下php找出sn來的,你可以試試
<?
// 大数十六进制转十进制字符串表示
function bchexdec($hex) {
$dec = 0;
$len = strlen($hex);
for ($i = 1; $i <= $len; $i++) {
$dec = bcadd($dec, bcmul(strval(hexdec($hex[$i - 1])), bcpow('16', strval($len - $i))));
}
return $dec;
}
// 索引数组反转拼接 k3=v3,k2=v2,k1=v1
function issuersToString($issuers){
$issuer_arr = [];
foreach ($issuers as $key => $val) {
$issuer_arr[] = $key . '=' . $val;
}
return implode(',', array_reverse($issuer_arr));
}
// 生成应用证书SN
function getCertSN() {
$cert = file_get_contents('./appCertPublicKey_2021001104697912.crt');
$certdata = openssl_x509_parse($cert);
// 支付宝应用公钥应当可以不要下面的分支逻辑
// 需要检查是否为十六进制
if (strpos($certdata['serialNumber'], '0x') === 0) {
// 转换十进制表示
$serialNumber = bchexdec($certdata['serialNumber']);
} else {
$serialNumber = $certdata['serialNumber'];
}
// 拼装issuser串
$issuer = issuersToString($certdata['issuer']);
echo md5($issuer . $serialNumber);
return md5($issuer . $serialNumber);
}
// 生成支付宝根证书SN
function getRootCertSN() {
// 读取证书内容
$cert = file_get_contents('./alipayRootCert.crt');
$split_str = "-----END CERTIFICATE-----";
// 证书链分割为多个证书部分
$cert_parts = explode($split_str, $cert);
$md5_arr = [];
foreach ($cert_parts as $part) {
if (!empty(trim($part))) {
// 完整结构表示
$cert = $part . $split_str;
$certdata = openssl_x509_parse($cert);
// 仅检查 signatureTypeSN='RSA-SHA256', 'RSA-SHA1'
// 或者检查 signatureTypeLN='sha256WithRSAEncryption','sha1WithRSAEncryption'
if (in_array($certdata['signatureTypeSN'], ['RSA-SHA256', 'RSA-SHA1'])) {
// 需要检查是否为十六进制
// 例如 CN=iTrusChina Class 2 Root CA - G3 证书的serialNumber则为0x开头
if (strpos($certdata['serialNumber'], '0x') === 0) {
// 转换十进制表示
$serialNumber = bchexdec($certdata['serialNumber']);
} else {
$serialNumber = $certdata['serialNumber'];
}
// 拼装issuser串
$issuer = issuersToString($certdata['issuer']);
// 追加每个证书serialNumber结果
$md5_arr[] = md5($issuer . $serialNumber);
}
}
}
// 最后使用 _ 连接
echo implode('_', $md5_arr);
return implode('_', $md5_arr);
}
getRootCertSN();
getCertSN();
?>
@cheuk3 我这个得到是 66 位的字符串数据
let publicdata = { charset: "UTF-8", method: "alipay.fund.trans.uni.transfer", timestamp: , version: "1.0", appCertSn: 'xxxx', alipayRootCertSn: '687b59f3d3b83462e1dfcf6', bizContent: biz_content };
const alipaySdk = new AlipaySdk({ appId: '', privateKey: fs.readFileSync(think.ROOT_PATH + '//rsa_private_key.pem', 'ascii'), keyType: "PKCS8", });
我是用 c# sdk 搞出了sn 应该不会错吧
你的rootsn跟我的差別很大,我的不是21位的 所以我相信應該是sn不對
@cheuk3 我这个得到是 66 位的字符串数据
那應該正確了 你試試
应用公钥证书不存在 是什么问题 我这个证书都是从开放平台下载下来的 为什么还会出现证书不存在
@cheuk3
@cheuk3
应用公钥证书不存在 是什么问题 我这个证书都是从开放平台下载下来的 为什么还会出现证书不存在
你是在這裡下載的嗎
@cheuk3 文件名叫什么
@cheuk3 文件名叫什么
alipayCertPublicKey_RSA2 alipayRootCert
@cheuk3 我实在不知道哪里错了 头晕了 你是台湾还是香港的 不方便加qq吗
已经可以了 谢谢
已经可以了 谢谢
之前是什麼問題?
@cheuk3 不知道为什么 我在获取sn的时候 c#代码和java 获取出来的居然不一样 用java 获取出来的是正确的
我用nodejs 写了一个获取sn 的方法 https://github.com/alipay/alipay-sdk-nodejs-all/issues/62
如何使用证书签名方式请求?