支付宝公钥证书 PHP 版本 SDK(用于现金红包等业务)

支付宝某些业务只能使用公钥证书方式来验签,但是只有JAVA版本的SDK。所以转载一下大佬们做的PHP版本SDK供大家使用。
原文地址:https://developer.aliyun.com/ask/138868 ,要往下翻一点,2019-09-12 13:28:54日用户1628209366284721 发的帖。

function getRootCertSN($str)
    {
        // return '687b59193f3f462dd5336e5abf83c5d8_02941eef3187dddf3d3b83462e1dfcf6';
        $arr = preg_split('/(?=-----BEGIN)/', $str, -1, PREG_SPLIT_NO_EMPTY);
        $str = null;
        foreach ($arr as $e) {
            $sn = getCertSN($e, true);
            if (!$sn) {
                continue;
            }
            if ($str === null) {
                $str = $sn;
            } else {
                $str .= "_" . $sn;
            }
        }
        return $str;
    }

    function getCertSN($str, $matchAlgo = false)
    {
        /*
        根据java SDK源码:AntCertificationUtil::getRootCertSN
        对证书链中RSA的项目进行过滤(猜测是gm国密算法java抛错搞不定,故意略去)
        java源码为:

        if(c.getSigAlgOID().startsWith("1.2.840.113549.1.1"))

        根据 https://www.alvestrand.no/objectid/1.2.840.113549.1.1.html
        该OID为RSA算法系。
         */
        if ($matchAlgo) {
            openssl_x509_export($str, $out, false);
            if (!preg_match('/Signature Algorithm:.*?RSA/im', $out, $m)) {
                return;
            }

        }
        $a = openssl_x509_parse($str);
        $issuer = null;
        // 注意:根据java代码输出,需要倒着排列 CN,OU,O
        foreach ($a["issuer"] as $k => $v) {
            if ($issuer === null) {
                $issuer = "$k=$v";
            } else {
                $issuer = "$k=$v," . $issuer;
            }
        }
        #    echo($issuer . $a["serialNumber"] . "\n");
        $serialNumberHex = decimalNotation($a['serialNumberHex']);
        $sn = md5($issuer . $serialNumberHex);
        return $sn;
    }

    function decimalNotation($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;
    }

然后在公共请求参数里面传递app_cert_snalipay_root_cert_sn两个参数即可。

本作品采用《CC 协议》,转载必须注明作者和本文链接
原创。 所有 Laravel 文章均已收录至 Github laravel-tips 项目。
Ίκαρος
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!