一般设计安全性比较高的三方支付 会采用公私钥这种方式进行加密和解密 话不多说 先说下常见问题
问题1
openssl_sign(): supplied key param cannot be coerced into a private key出现这种问题是私匙的文件格式不对
可以通道下列方法更正
$value是私钥
public function setPrivateKey($value, $passphrase = ''){
if(is_file($value)) $value = file_get_contents($value);
$value = chunk_split($value, 64, "\n");//64个字符就换行
$value = "-----BEGIN RSA PRIVATE KEY-----\n$value-----END RSA PRIVATE KEY-----\n";//拼装组合开头和结尾
//$this->privateKey = openssl_pkey_get_private($value, $passphrase); 返回格式符合的私钥
return openssl_pkey_get_private($value, $passphrase);//openssl_pkey_get_private函数成功,返回真实的密钥资源标识符,失败,返回 FALSE .
}
问题2 $data是序列化后的请求参数 $private_key是秘钥 rsaSign方法是将参数和秘钥一起生成要加密的签名
如果用rsaSign生成签名的时候报问题1 的错误 可以对私钥进行问题1中的setPrivateKey方法矫正就可以避免了
private function rsaSign($data,$private_key){
$res = openssl_get_privatekey($private_key);
openssl_sign($data, $sign, $res,OPENSSL_ALGO_SHA1);
openssl_free_key($res);
$sign = base64_encode($sign);
return $sign;
}
问题3 回调的签名验证问题
私钥加密 公钥解密 $arr是回调返回的参数 sign是签名 rsaverify_string函数对回调进行验签 将得到的签名和参数里的签名进行对比 一致的话说明数据没有修改/**
2 * 校验签名
@$data为签名的数组数据
3 * @param string $pubKey 公钥
4 * @param string $sign 返回的签名
5 * @param string $string 待签名字符串
6 * @param string $signature_alg 签名方式 比如 sha1WithRSAEncryption 或者sha512
7 * @return bool
8 */
public function rsaVerify($data)
{
//$sign为对方返回的签名串
$sign = base64_decode($data['sign']);
$string = $this->formatSignatureString($data);
$pub_key_id = openssl_pkey_get_public($this->setPublicKey($this->publickey));
$result = (bool) openssl_verify($string, $sign, $pub_key_id, OPENSSL_ALGO_SHA1);
openssl_free_key($pub_key_id);
return $result;
}
private function formatSignatureString($data)
{
ksort($data);
$string = [];
foreach ($data as $key => $value) {
if ($key != 'sign' && $key != '' && $value != '') {
$string[] = $key . '=' . $value;
}
}
$string = join('&', $string);
return $string;
}