我们在处理支付宝支付回调地址的时候,有时候会发现下面的错误提示
openssl_verify(): supplied key param cannot be coerced into a public key
其实总的来说,就是证书的问题
我们先来看一下这几个函数
/** rsaCheckV1 & rsaCheckV2 * 验证签名 * 在使用本方法前,必须初始化AopClient且传入公钥参数。 * 公钥是否是读取字符串还是读取文件,是根据初始化传入的值判断的。 **/ public function rsaCheckV1($params, $rsaPublicKeyFilePath,$signType='RSA') { $sign = $params['sign']; $params['sign_type'] = null; $params['sign'] = null; return $this->verify($this->getSignContent($params), $sign, $rsaPublicKeyFilePath,$signType); } public function rsaCheckV2($params, $rsaPublicKeyFilePath, $signType='RSA') { $sign = $params['sign']; $params['sign'] = null; return $this->verify($this->getSignContent($params), $sign, $rsaPublicKeyFilePath, $signType); } function verify($data, $sign, $rsaPublicKeyFilePath, $signType = 'RSA') { if($this->checkEmpty($this->alipayPublicKey)){ $pubKey= $this->alipayrsaPublicKey; $res = "-----BEGIN PUBLIC KEY-----\n" . wordwrap($pubKey, 64, "\n", true) . "\n-----END PUBLIC KEY-----"; }else { //读取公钥文件 $pubKey = file_get_contents($rsaPublicKeyFilePath); //转换为openssl格式密钥 $res = openssl_get_publickey($pubKey); } ($res) or die('支付宝RSA公钥错误。请检查公钥文件格式是否正确'); //调用openssl内置方法验签,返回bool值 $result = FALSE; if ("RSA2" == $signType) { $result = (openssl_verify($data, base64_decode($sign), $res, OPENSSL_ALGO_SHA256)===1); } else { $result = (openssl_verify($data, base64_decode($sign), $res)===1); } if(!$this->checkEmpty($this->alipayPublicKey)) { //释放资源 openssl_free_key($res); } return $result; }
注意看verify这个函数的所传的参数$rsaPublicKeyFilePath,仔细看参数命名的话,这里传的是支付宝公钥文件路径,当路径为空的时候会获取$this->alipayPublicKey这个证书字符串。
我们很多人在这里的参数直接传入证书支付宝证书字符串,所以$rsaPublicKeyFilePath不为空,但字符串也不是路径,所以就报错了。
解决办法:
如果我们的支付宝公钥存在文件里面,那么在回调地址里面的第二个参数直接传入支付宝公钥的路径
$Aop->rsaCheckV1($arr,$alipayConfigTcw['rsaPublicKeyFilePath'], $alipayConfigTcw['signType']);
如果,如果支付宝公钥是写配置文件或者数据库里的一个字符串,那么我们就需要通过别的方式把支付宝公钥字符串传入到类里面的$this->alipayrsaPublicKey,并且$alipayConfigTcw['rsaPublicKeyFilePath']这个参数要传入空值。
如下:
$Aop = new \AopClient(); $Aop->alipayrsaPublicKey = '支付宝公钥字符串'; //第二个参数传入空值就行了 $result = $Aop->rsaCheckV1($arr,‘’, $alipayConfigTcw['signType']);