<?php
// +----------------------------------------------------------------------
// | Author: savy.liao
// | RSA验证签名算法
// +----------------------------------------------------------------------
namespace PiaoTongApi\Model;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\Cast\Int_;
use Think\Model;
use Think\Exception;
class LfRSAModel extends Model
{
private $public_key = ''; //公密钥
private $private_key = ''; //私密钥
private $public_key_resource = ''; //公密钥资源
private $private_key_resource = ''; //私密钥资源
/**
* 架构函数
* @param [string] $public_key [公密钥]
* @param [string] $private_key [私密钥]
*/
public function __construct($public_keys,$private_keys) {
$this->public_key = $public_keys;
$this->private_key = $private_keys;
try {
if (empty($this->public_key) || empty($this->private_key)) {
throw new Exception('key is not valid');
}
$public_pem = chunk_split($this->public_key,64,"\n");//转换为pem格式的公钥
$this->public_key = "-----BEGIN PUBLIC KEY-----\n".$public_pem."-----END PUBLIC KEY-----\n";
$private_pem = chunk_split($this->private_key,64,"\n");//转换为pem格式的私钥
$this->private_key = "-----BEGIN PRIVATE KEY-----\n".$private_pem."-----END PRIVATE KEY-----\n";
if(false == ($this->public_key_resource = $this->is_bad_public_key($this->public_key)) || false == ($this->private_key_resource = $this->is_bad_private_key($this->private_key))) {
throw new Exception('public key or private key no usable');
}
} catch (Exception $e) {
die($e->getMessage());
}
}
private function is_bad_public_key($public_key) {
//这个函数可用来判断公钥是否是可用的
return openssl_pkey_get_public($public_key);
}
private function is_bad_private_key($private_key) {
///这个函数可用来判断私钥是否是可用的,可用返回资源id Resource id
return openssl_pkey_get_private($private_key);
}
/**
* 生成一对公私密钥 成功返回 公私密钥数组 失败 返回 false
*/
public function create_key() {
$res = openssl_pkey_new();
if($res == false) return false;
openssl_pkey_export($res, $private_key);
$public_key = openssl_pkey_get_details($res);
return array('public_key'=>$public_key["key"],'private_key'=>$private_key);
}
/**
* 用私密钥加密
*/
public function private_encrypt($input) {
openssl_private_encrypt($input,$output,$this->private_key_resource);
return base64_encode($output);//加密后的内容通常含有特殊字符,需要编码转换下,在网络间通过url传输时要注意base64编码是否是url安全的
}
/**
* 解密 私密钥加密后的密文
*/
public function public_decrypt($input) {
//私钥加密的内容通过公钥可用解密出来
openssl_public_decrypt(base64_decode($input),$output,$this->public_key_resource);
return $output;
}
/**
* 用公密钥加密
*/
public function public_encrypt($input) {
$output = '';
foreach (str_split($input, 117) as $chunk) {
// 加密的时候117个字符加密一次,然后把所有的密文拼接成一个密文;然后拼接成数据。
openssl_public_encrypt(str_pad($chunk, 128, "\0", STR_PAD_LEFT), $encryptData, $this->public_key_resource, OPENSSL_NO_PADDING);
$output .= $encryptData;
}
return base64_encode($output);//加密后的内容通常含有特殊字符,需要编码转换下,在网络间通过url传输时要注意base64编码是否是url安全的
}
/**
* 解密 公密钥加密后的密文
*/
public function private_decrypt($input) {
//公钥加密的内容通过私钥可用解密出来
$output = '';
foreach (str_split(base64_decode($input), 128) as $chunk) {
//解密的时候需要128个字符解密一下
openssl_private_decrypt($chunk, $decryptData, $this->private_key_resource);
$output .= $decryptData;
}
return $output;
}
/**
* 签名-私钥
*/
public function sign($input){
openssl_sign($input,$sign,$this->private_key_resource);
$sign = base64_encode($sign);//最终的签名
return $sign;
}
/**
* 验签-公钥
*/
public function verify($data,$sign){
//调用openssl内置方法验签,返回bool值
$result = (bool)openssl_verify($data, base64_decode($sign), $this->public_key_resource);
//返回资源是否成功
return $result;
}
public function __destruct () {
//释放资源
openssl_free_key($this->public_key_resource);
openssl_free_key($this->private_key_resource);
}
}
?>