您现在的位置是:首页 > 其他

李清波 2019-08-23 其他 69

openssl_sign(): supplied key param cannot be coerced into a private key

我们在处理支付宝支付回调地址的时候,有时候会发现下面的错误提示

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']);


评论