使用RSA算法除了加密解密之外(加密解密的代码可以查看本站PHP使用RSA算法加密解密数据 这篇文章),在支付等接口方面通常还会用到生成签名和验证签名操作,下面是PHP代码:
class RSA
{
/**
* RSA签名
* @param $data 待签名数据
* @param $private_key 私钥字符串
* return 签名结果
*/
function rsaSign($data, $private_key) {
$search = [
"-----BEGIN RSA PRIVATE KEY-----",
"-----END RSA PRIVATE KEY-----",
"\n",
"\r",
"\r\n"
];
$private_key=str_replace($search,"",$private_key);
$private_key=$search[0] . PHP_EOL . wordwrap($private_key, 64, "\n", true) . PHP_EOL . $search[1];
$res=openssl_get_privatekey($private_key);
if($res)
{
openssl_sign($data, $sign,$res);
openssl_free_key($res);
}else {
exit("私钥格式有误");
}
$sign = base64_encode($sign);
return $sign;
}
/**
* RSA验签
* @param $data 待签名数据
* @param $public_key 公钥字符串
* @param $sign 要校对的的签名结果
* return 验证结果
*/
function rsaCheck($data, $public_key, $sign) {
$search = [
"-----BEGIN PUBLIC KEY-----",
"-----END PUBLIC KEY-----",
"\n",
"\r",
"\r\n"
];
$public_key=str_replace($search,"",$public_key);
$public_key=$search[0] . PHP_EOL . wordwrap($public_key, 64, "\n", true) . PHP_EOL . $search[1];
$res=openssl_get_publickey($public_key);
if($res)
{
$result = (bool)openssl_verify($data, base64_decode($sign), $res);
openssl_free_key($res);
}else{
exit("公钥格式有误!");
}
return $result;
}
}
$str = '11223344';
echo '待签名的数据是' . $str . '<hr>';
$obj = new RSA();
$sign = $obj->rsaSign($str,file_get_contents('./private.txt'));
echo '签名后的数据是' . $sign . '<hr>';
if($obj->rsaCheck($str,file_get_contents('./public.txt'),$sign)){
echo '验证成功';
}else{
echo '验证失败';
}
如果使用RSA2也比较简单只需要在签名和验签的函数里面多增加一个参数OPENSSL_ALGO_SHA256就可以了,改进如下:
//签名 RSA2
openssl_sign($data, $sign,$res,OPENSSL_ALGO_SHA256);
//验签 RSA2
openssl_verify($data, base64_decode($sign), $res,OPENSSL_ALGO_SHA256);