我们在处理支付宝支付回调地址的时候,有时候会发现下面的错误提示
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']);