first commit
This commit is contained in:
467
pgserver/application/lib/AuthApi.php
Normal file
467
pgserver/application/lib/AuthApi.php
Normal file
@@ -0,0 +1,467 @@
|
||||
<?php
|
||||
|
||||
namespace app\lib;
|
||||
|
||||
|
||||
use app\util\ReturnCode;
|
||||
use think\facade\Env;
|
||||
use \Exception;
|
||||
|
||||
/**
|
||||
* 权限系统接口
|
||||
*/
|
||||
class AuthApi
|
||||
{
|
||||
//调用信息
|
||||
// const USERNAME = 'auth';
|
||||
const USERNAME = 'nce';
|
||||
// const PASSWORD = 'YlzXZbm4&5';
|
||||
const PASSWORD = 'NRXpT@HfvH';
|
||||
const GRANT_TYPE = 'refresh_token';
|
||||
|
||||
// 接口IP
|
||||
//const AUTH_URL = 'http://106.52.70.137:8080/';
|
||||
// const AUTH_URL = 'http://111.230.221.71:8001/';
|
||||
// const AUTH_URL = 'http://129.204.123.130:8001/'; // uat
|
||||
private $auth_url;
|
||||
//接口地址
|
||||
const API_TOKEN = 'auth/oauth/token'; //获取token接口/刷新token接口
|
||||
const API_TOKEN1 = 'oauth/token'; //获取token接口/刷新token接口
|
||||
const API_DEL_TOKEN = '/logout'; //注销token接口
|
||||
const API_USER_AUTH = 'auth/api/user/per'; //获取用户权限
|
||||
const API_USER_ROLE = 'auth/api/user/role'; //获取角色用户
|
||||
const API_USER_LIST = 'auth/api/user/list'; //获取用户列表
|
||||
const API_DEPART_ROLE = 'auth/api/user/depart/users'; //根据部门id获取用户信息
|
||||
const API_BUSINESS_DEPARTMENT = 'auth/api/user/depart'; //根据业务部id获取业务部下属所有分部信息
|
||||
const API_MANY_USER_ROLE = 'auth/api/user/roles'; //获取多角色用户
|
||||
const API_QR_CODE = 'auth/user/token'; // 扫码登录获取token接口
|
||||
const API_UPDATE_PWD = 'system/user/profile/updatePwd'; // 扫码登录获取token接口
|
||||
// const API_TOKEN = 'CLOUD-AUTH/oauth/token'; //获取token接口/刷新token接口
|
||||
// const API_TOKEN1 = 'oauth/token'; //获取token接口/刷新token接口
|
||||
// const API_DEL_TOKEN = 'CLOUD-AUTH/api/exit'; //注销token接口
|
||||
// const API_USER_AUTH = 'CLOUD-AUTH/api/user/per'; //获取用户权限
|
||||
// const API_USER_ROLE = 'CLOUD-AUTH/api/user/role'; //获取角色用户
|
||||
// const API_DEPART_ROLE = 'CLOUD-AUTH/api/user/depart/users'; //根据部门id获取用户信息
|
||||
// const API_BUSINESS_DEPARTMENT = 'CLOUD-AUTH/api/user/depart'; //根据业务部id获取业务部下属所有分部信息
|
||||
// const API_MANY_USER_ROLE = 'CLOUD-AUTH/api/user/roles'; //获取多角色用户
|
||||
// const API_QR_CODE = 'CLOUD-AUTH/user/token'; // 扫码登录获取token接口
|
||||
|
||||
public function __construct(){
|
||||
$this->auth_url = Env::get('auth.auth_url');
|
||||
}
|
||||
/**
|
||||
* GET 请求
|
||||
* @param string $url
|
||||
*/
|
||||
private function http_get($url,$param,$arr_header=array(),$id=''){
|
||||
$oCurl = curl_init();
|
||||
if (is_string($param)) {
|
||||
$strPOST = $param;
|
||||
} else {
|
||||
$aPOST = array();
|
||||
foreach ($param as $key => $val) {
|
||||
$aPOST[] = $key . "=" . $val;
|
||||
}
|
||||
$strPOST = join("&", $aPOST);
|
||||
}
|
||||
$url = $url."?".$strPOST;
|
||||
if (stripos($url, "https://") !== false) {
|
||||
curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
|
||||
}
|
||||
curl_setopt($oCurl, CURLOPT_URL, $url);
|
||||
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1);
|
||||
if(!empty($arr_header)){
|
||||
$arr_header[] = "Content-Type: application/json; charset=utf-8";
|
||||
}
|
||||
curl_setopt($oCurl, CURLOPT_HTTPHEADER, $arr_header);
|
||||
|
||||
$sContent = curl_exec($oCurl);
|
||||
if (curl_errno($oCurl)){
|
||||
throw new Exception(curl_error($oCurl),0);
|
||||
}else{
|
||||
$httpStatusCode = curl_getinfo($oCurl, CURLINFO_HTTP_CODE);
|
||||
if (200 !== $httpStatusCode){
|
||||
|
||||
throw new Exception($arr_header[1],$httpStatusCode);
|
||||
}
|
||||
}
|
||||
curl_close($oCurl);
|
||||
return $sContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* POST 请求
|
||||
* @param string $url
|
||||
* @param array $param
|
||||
* @param boolean $post_file 是否文件上传
|
||||
* @param boolean $time 超时时间,单位秒
|
||||
* @param boolean $id 爬虫日志表id
|
||||
* @param boolean $arr_header http请求头
|
||||
* @return string content
|
||||
*/
|
||||
private function http_post($url, $param,$user_name,$password, $post_file = false, $time = 30,$id='',$arr_header=array()){
|
||||
$oCurl = curl_init();
|
||||
if (stripos($url, "https://") !== false) {
|
||||
curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
|
||||
|
||||
if(stripos($url,"pycredit")!== false){
|
||||
curl_setopt($oCurl, CURLOPT_SSLCERT, APP_PATH . 'extra' . DS . self::PYCERT_NAME); //pem
|
||||
curl_setopt($oCurl, CURLOPT_SSLCERTPASSWD, '123456');
|
||||
curl_setopt($oCurl, CURLOPT_SSLKEY, APP_PATH . 'extra' . DS . self::PYCERT_NAME); //pem
|
||||
curl_setopt($oCurl, CURLOPT_SSLKEYPASSWD, '123456'); //pem
|
||||
}
|
||||
}
|
||||
if (is_string($param) || $post_file) {
|
||||
$strPOST = $param;
|
||||
} else {
|
||||
$aPOST = array();
|
||||
foreach ($param as $key => $val) {
|
||||
$aPOST[] = $key . "=" . $val;
|
||||
}
|
||||
$strPOST = join("&", $aPOST);
|
||||
}
|
||||
|
||||
curl_setopt($oCurl, CURLOPT_URL, $url);
|
||||
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($oCurl, CURLOPT_POST, true);
|
||||
curl_setopt($oCurl, CURLOPT_TIMEOUT, $time); //只需要设置一个秒的数量就可以,超时时间
|
||||
curl_setopt($oCurl, CURLOPT_POSTFIELDS, $strPOST);
|
||||
// curl_setopt($oCurl, CURLOPT_HTTPHEADER, $arr_header);
|
||||
curl_setopt($oCurl, CURLOPT_USERPWD, "{$user_name}:{$password}");
|
||||
$sContent = curl_exec($oCurl);
|
||||
$aStatus = curl_getinfo($oCurl);
|
||||
curl_close($oCurl);
|
||||
|
||||
if (intval($aStatus["http_code"]) == 200) {
|
||||
return $sContent;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DELETE 请求
|
||||
* @param string $url
|
||||
* @param array $param
|
||||
* @param boolean $user_name AUTH账号
|
||||
* @param boolean $password AUTH密码
|
||||
* @return string content
|
||||
*/
|
||||
function http_delete($url,$param,$user_name,$password) {
|
||||
$oCurl = curl_init();
|
||||
|
||||
if (is_string($param)) {
|
||||
$strPOST = $param;
|
||||
} else {
|
||||
$aPOST = array();
|
||||
foreach ($param as $key => $val) {
|
||||
$aPOST[] = $key . "=" . $val;
|
||||
}
|
||||
$strPOST = join("&", $aPOST);
|
||||
}
|
||||
$url = $url."?".$strPOST;
|
||||
|
||||
curl_setopt($oCurl, CURLOPT_URL, $url);
|
||||
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($oCurl, CURLOPT_CUSTOMREQUEST, 'DELETE');
|
||||
|
||||
//设置头
|
||||
curl_setopt($oCurl, CURLOPT_USERPWD, "{$user_name}:{$password}");
|
||||
curl_setopt($oCurl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36');
|
||||
|
||||
curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, false);//SSL认证。
|
||||
$sContent = curl_exec($oCurl);
|
||||
$aStatus = curl_getinfo($oCurl);
|
||||
|
||||
curl_close($oCurl);
|
||||
|
||||
if (intval($aStatus["http_code"]) == 200) {
|
||||
return $sContent;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* PUT 请求
|
||||
* @param string $url
|
||||
* @param array $param
|
||||
* @param boolean $user_name AUTH账号
|
||||
* @param boolean $password AUTH密码
|
||||
* @return string content
|
||||
*/
|
||||
function http_put($url,$param,$user_name,$password, $arr_header) {
|
||||
$oCurl = curl_init();
|
||||
|
||||
if (is_string($param)) {
|
||||
$strPOST = $param;
|
||||
} else {
|
||||
$aPOST = array();
|
||||
foreach ($param as $key => $val) {
|
||||
$aPOST[] = $key . "=" . $val;
|
||||
}
|
||||
$strPOST = join("&", $aPOST);
|
||||
}
|
||||
$url = $url."?".$strPOST;
|
||||
|
||||
curl_setopt($oCurl, CURLOPT_URL, $url);
|
||||
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($oCurl, CURLOPT_CUSTOMREQUEST, 'PUT');
|
||||
|
||||
//设置头
|
||||
curl_setopt($oCurl, CURLOPT_HTTPHEADER, $arr_header);
|
||||
// curl_setopt($oCurl, CURLOPT_USERPWD, "{$user_name}:{$password}");
|
||||
curl_setopt($oCurl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36');
|
||||
|
||||
curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, false);//SSL认证。
|
||||
$sContent = curl_exec($oCurl);
|
||||
$aStatus = curl_getinfo($oCurl);
|
||||
|
||||
curl_close($oCurl);
|
||||
|
||||
if (intval($aStatus["http_code"]) == 200) {
|
||||
return $sContent;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* getToken
|
||||
* @Author
|
||||
* @DateTime
|
||||
* @version 1.0
|
||||
* @param data 查询条件json
|
||||
* @return string 查询结果json字符串
|
||||
*/
|
||||
public function getToken($data){
|
||||
if (empty($data)) {
|
||||
return ReturnCode::AUTH_PARAMETER;
|
||||
}
|
||||
$apiFrom = self::API_TOKEN;
|
||||
$url = $this->auth_url . $apiFrom;
|
||||
$user_name = self::USERNAME;
|
||||
$password = self::PASSWORD;
|
||||
$res = $this->http_post($url, $data,$user_name,$password, false, 120);
|
||||
if ($res) {
|
||||
return $res;
|
||||
} else {
|
||||
return ReturnCode::AUTH_TOKEN;
|
||||
}
|
||||
}
|
||||
|
||||
public function getQrCodeToken($data){
|
||||
if (empty($data)) {
|
||||
return ReturnCode::AUTH_PARAMETER;
|
||||
}
|
||||
$apiFrom = self::API_QR_CODE;
|
||||
$url = $this->auth_url . $apiFrom;
|
||||
$user_name = self::USERNAME;
|
||||
$password = self::PASSWORD;
|
||||
$res = $this->http_post($url, $data,$user_name,$password, false, 120);
|
||||
if ($res) {
|
||||
return $res;
|
||||
} else {
|
||||
return ReturnCode::AUTH_TOKEN;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* userinfo
|
||||
* @Author
|
||||
* @DateTime
|
||||
* @version 1.0
|
||||
* @param data 查询条件
|
||||
* @return string 查询结果json字符串
|
||||
*/
|
||||
public function userinfo($data,$arr_header)
|
||||
{
|
||||
if (empty($data)) {
|
||||
return ReturnCode::AUTH_USER_TOKEN;
|
||||
}
|
||||
$apiFrom = self::API_USER_AUTH;
|
||||
$url = $this->auth_url . $apiFrom;
|
||||
$res = $this->http_get($url,$data,$arr_header);
|
||||
if ($res) {
|
||||
return $res;
|
||||
} else {
|
||||
return ReturnCode::AUTH_USER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logout
|
||||
* @Author llz
|
||||
* @DateTime 2022-10-10
|
||||
* @version 1.0
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
public function Logout($data)
|
||||
{
|
||||
if (empty($data)) {
|
||||
return ReturnCode::AUTH_USER_TOKEN;
|
||||
}
|
||||
$apiFrom = self::API_DEL_TOKEN;
|
||||
$url = $this->auth_url . $apiFrom;
|
||||
$user_name = self::USERNAME;
|
||||
$password = self::PASSWORD;
|
||||
$res = $this->http_delete($url,$data,$user_name,$password);
|
||||
|
||||
if ($res) {
|
||||
return $res;
|
||||
} else {
|
||||
return ReturnCode::AUTH_USER;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* userinfo
|
||||
* @Author
|
||||
* @DateTime
|
||||
* @version 1.0
|
||||
* @param data 查询条件
|
||||
* @return string 查询结果json字符串
|
||||
*/
|
||||
public function RefreshgetToken($userid,$refresh_token)
|
||||
{
|
||||
if (empty($refresh_token)) {
|
||||
return ReturnCode::AUTH_PARAMETER;
|
||||
}
|
||||
$apiFrom = self::API_TOKEN;
|
||||
|
||||
$userInfo = cache('userinfo'.$userid);
|
||||
$url = $this->auth_url . $apiFrom."?grant_type=".self::GRANT_TYPE."&refresh_token=".$refresh_token;
|
||||
$user_name = $userInfo['user_name'];
|
||||
$password = self::PASSWORD;
|
||||
$res = $this->http_post($url, array(),$user_name,$password, false, 120);
|
||||
|
||||
if ($res) {
|
||||
return $res;
|
||||
} else {
|
||||
return ReturnCode::AUTH_TOKEN;
|
||||
}
|
||||
}
|
||||
|
||||
public function getRole($data,$arr_header) {
|
||||
if (empty($data)) {
|
||||
return ReturnCode::AUTH_PARAMETER;
|
||||
}
|
||||
$apiFrom = self::API_USER_ROLE;
|
||||
$url = $this->auth_url . $apiFrom;
|
||||
$res = $this->http_get($url,$data);
|
||||
if ($res) {
|
||||
return $res;
|
||||
} else {
|
||||
return ReturnCode::AUTH_ROLE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据部门id获取用户列表
|
||||
* @param [type] $data [description]
|
||||
* @return [type] [description]
|
||||
*/
|
||||
public function getUsersListById($data) {
|
||||
if (empty($data)) {
|
||||
return ReturnCode::AUTH_PARAMETER;
|
||||
}
|
||||
$apiFrom = self::API_DEPART_ROLE;
|
||||
$url = $this->auth_url . $apiFrom;
|
||||
$res = $this->http_get($url,$data);
|
||||
if ($res) {
|
||||
return $res;
|
||||
} else {
|
||||
return ReturnCode::AUTH_ROLE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据业务部id获取业务部下面所有部门信息
|
||||
* @param $data
|
||||
* @return array|int
|
||||
*/
|
||||
public function getBusinessDepartment($data) {
|
||||
if (empty($data)) {
|
||||
return ReturnCode::AUTH_PARAMETER;
|
||||
}
|
||||
$apiFrom = self::API_BUSINESS_DEPARTMENT;
|
||||
$url = $this->auth_url . $apiFrom;
|
||||
$res = $this->http_get($url,$data);
|
||||
if ($res) {
|
||||
return $res;
|
||||
} else {
|
||||
return ReturnCode::AUTH_ROLE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* getUser
|
||||
* @Author
|
||||
* @DateTime
|
||||
* @version 1.0
|
||||
* @param data 查询条件json
|
||||
* @return string 查询结果json字符串
|
||||
*/
|
||||
public function getUser($data){
|
||||
if (empty($data)) {
|
||||
return ReturnCode::AUTH_PARAMETER;
|
||||
}
|
||||
$apiFrom = self::API_MANY_USER_ROLE;
|
||||
|
||||
$url = $this->auth_url . $apiFrom;
|
||||
$data['systemCode'] = 'NCE';
|
||||
$res = $this->http_get($url,$data);
|
||||
|
||||
if ($res) {
|
||||
return $res;
|
||||
} else {
|
||||
return ReturnCode::AUTH_TOKEN;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* getUserList
|
||||
* @Author llz
|
||||
* @DateTime 2023-3-09
|
||||
* @version 1.0
|
||||
* @return string 查询结果json字符串
|
||||
*/
|
||||
public function getUserList(){
|
||||
$url = $this->auth_url . self::API_USER_LIST;
|
||||
|
||||
$res = $this->http_get($url,[]);
|
||||
|
||||
if ($res) {
|
||||
return $res;
|
||||
} else {
|
||||
return ReturnCode::DB_READ_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* updatePwd
|
||||
* @Author llz
|
||||
* @DateTime 2023-3-09
|
||||
* @version 1.0
|
||||
* @return string 查询结果json字符串
|
||||
*/
|
||||
public function updatePwd(array $data, array $arr_header): string
|
||||
{
|
||||
if (empty($data)) {
|
||||
return ReturnCode::AUTH_PARAMETER;
|
||||
}
|
||||
$apiFrom = self::API_UPDATE_PWD;
|
||||
$url = $this->auth_url . $apiFrom;
|
||||
$res = $this->http_put($url, $data, self::USERNAME, self::PASSWORD, $arr_header);
|
||||
if ($res) {
|
||||
return $res;
|
||||
} else {
|
||||
return ReturnCode::AUTH_USER;
|
||||
}
|
||||
}
|
||||
}
|
||||
101
pgserver/application/lib/BOC/BocCipherUtil.php
Normal file
101
pgserver/application/lib/BOC/BocCipherUtil.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace app\lib\BOC;
|
||||
|
||||
class BocCipherUtil {
|
||||
private const ENCODING = 'UTF-8';
|
||||
private const ALGORITHM_NAME = 'SM4';
|
||||
private const ALGORITHM_NAME_ECB_PADDING = 'SM4-ECB';
|
||||
private const DEFAULT_KEY_SIZE = 128;
|
||||
|
||||
/**
|
||||
* 生成ECB模式的SM4加密器/解密器
|
||||
* @param string $algorithmName 算法名称
|
||||
* @param int $mode 模式:OPENSSL_ENCRYPT或OPENSSL_DECRYPT
|
||||
* @param string $key 密钥
|
||||
* @return array 加密/解密参数
|
||||
*/
|
||||
private static function generateEcbCipher($algorithmName, $mode, $key) {
|
||||
return [
|
||||
'cipher' => $algorithmName,
|
||||
'key' => $key,
|
||||
'options' => OPENSSL_RAW_DATA,
|
||||
'iv' => '' // ECB模式不需要IV
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成SM4密钥
|
||||
* @param int $keySize 密钥大小
|
||||
* @return string 随机密钥
|
||||
*/
|
||||
public static function generateKey($keySize = self::DEFAULT_KEY_SIZE) {
|
||||
return openssl_random_pseudo_bytes($keySize / 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* SM4 ECB模式加密
|
||||
* @param string $hexKey 16进制密钥
|
||||
* @param string $paramStr 待加密字符串
|
||||
* @return string 16进制加密结果
|
||||
*/
|
||||
public static function encryptEcb($hexKey, $paramStr) {
|
||||
$key = hex2bin($hexKey);
|
||||
$srcData = $paramStr;
|
||||
|
||||
$cipherParams = self::generateEcbCipher(self::ALGORITHM_NAME_ECB_PADDING, OPENSSL_ENCRYPT, $key);
|
||||
$cipherArray = openssl_encrypt($srcData, $cipherParams['cipher'], $cipherParams['key'], $cipherParams['options'], $cipherParams['iv']);
|
||||
|
||||
return bin2hex($cipherArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* SM4 ECB模式加密(字节数组接口)
|
||||
* @param string $data 待加密数据
|
||||
* @param string $key 密钥
|
||||
* @return string 加密结果
|
||||
*/
|
||||
public static function encrypt_Ecb($data, $key) {
|
||||
$cipherParams = self::generateEcbCipher(self::ALGORITHM_NAME_ECB_PADDING, OPENSSL_ENCRYPT, $key);
|
||||
return openssl_encrypt($data, $cipherParams['cipher'], $cipherParams['key'], $cipherParams['options'], $cipherParams['iv']);
|
||||
}
|
||||
|
||||
/**
|
||||
* SM4 ECB模式解密
|
||||
* @param string $hexKey 16进制密钥
|
||||
* @param string $cipherText 16进制加密字符串
|
||||
* @return string 解密后的字符串
|
||||
*/
|
||||
public static function decryptEcb($hexKey, $cipherText) {
|
||||
$key = hex2bin($hexKey);
|
||||
$cipherData = hex2bin($cipherText);
|
||||
|
||||
$cipherParams = self::generateEcbCipher(self::ALGORITHM_NAME_ECB_PADDING, OPENSSL_DECRYPT, $key);
|
||||
$srcData = openssl_decrypt($cipherData, $cipherParams['cipher'], $cipherParams['key'], $cipherParams['options'], $cipherParams['iv']);
|
||||
|
||||
return $srcData;
|
||||
}
|
||||
|
||||
/**
|
||||
* SM4 ECB模式解密(字节数组接口)
|
||||
* @param string $cipherText 加密数据
|
||||
* @param string $key 密钥
|
||||
* @return string 解密结果
|
||||
*/
|
||||
public static function decrypt_Ecb($cipherText, $key) {
|
||||
$cipherParams = self::generateEcbCipher(self::ALGORITHM_NAME_ECB_PADDING, OPENSSL_DECRYPT, $key);
|
||||
return openssl_decrypt($cipherText, $cipherParams['cipher'], $cipherParams['key'], $cipherParams['options'], $cipherParams['iv']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证加密前后的字符串是否为同一数据
|
||||
* @param string $hexKey 16进制密钥
|
||||
* @param string $cipherText 16进制加密后的字符串
|
||||
* @param string $paramStr 加密前的字符串
|
||||
* @return bool 是否为同一数据
|
||||
*/
|
||||
public static function verifyEcb($hexKey, $cipherText, $paramStr) {
|
||||
$decryptStr = self::decryptEcb($hexKey, $cipherText);
|
||||
return $decryptStr === $paramStr;
|
||||
}
|
||||
}
|
||||
371
pgserver/application/lib/BOCApi.php
Normal file
371
pgserver/application/lib/BOCApi.php
Normal file
@@ -0,0 +1,371 @@
|
||||
<?php
|
||||
|
||||
namespace app\lib;
|
||||
|
||||
use app\util\Tools;
|
||||
use app\util\ReturnCode;
|
||||
use think\facade\Response;
|
||||
use think\facade\Env;
|
||||
use \Exception;
|
||||
use app\util\Aes;
|
||||
use think\facade\Log;
|
||||
|
||||
/**
|
||||
* 中国银行系统接口
|
||||
* Sign(签名)是接口验证安全性的一种常用技术,在一定程度上可以保证数据接口的安全性,Sign一般都需要配合加密算法来使用,
|
||||
* 常用的AES系列算法(对称算法)、SHA系列算法(安全散列算法)、RSA系列算法(非对称算法)
|
||||
*/
|
||||
class BOCApi
|
||||
{
|
||||
//接收预评估结果接口
|
||||
const PRE_ESTIMATE_API = '/jkpt/pggsApi/estimate/receivePreResult';
|
||||
//接收正式评估结果接口
|
||||
const OFFICIAL_ESTIMATE_API = '/jkpt/pggsApi/estimate/receiveOff';
|
||||
|
||||
//const GY_AES_KEY = "bocguoyupinggupf";
|
||||
const TEST_GY_RSA_PUBLIC_KEY_STR = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDKOUoNyzZQER1eeRySa5zbV21qPYGM6QE241M5JlTjkuYn4oYc8WTaTEM4BaQPwkleZ2fF71hy9v15DO9Bev03kXoZQZSHN6gapxERVBjBL5wIoRAGdUtkTAtBkbDFpfeO4WFD3Mxlye97WAlpp/yuvGnGuTvcNC3H8KkIH31zgQIDAQAB";
|
||||
const TEST_GY_RSA_PRIVATE_KEY_STR = "MIICXQIBAAKBgQDKOUoNyzZQER1eeRySa5zbV21qPYGM6QE241M5JlTjkuYn4oYc8WTaTEM4BaQPwkleZ2fF71hy9v15DO9Bev03kXoZQZSHN6gapxERVBjBL5wIoRAGdUtkTAtBkbDFpfeO4WFD3Mxlye97WAlpp/yuvGnGuTvcNC3H8KkIH31zgQIDAQABAoGAaiYyUhVGWDbzpKCMN+uW9afpvie09iNkyMwA5nHRg3ebqnoEjfLETrZTXnfPi5ofaxd6aHLfidFOchkxCb0mZvLko861Y8RHGeGt42nuA1FEQ+AEOW4Hjk40dOC1MwAtF45nmPjmXNxzytFyMZWVWgV4IS0CmqmIsJ0qq20bm9UCQQDnwGs6BxxQ09ifx75xz7FoR4ZVDrxd1lgtgI7RPRuVIrjTRUiWDIi8lfvqYkyIK+Xld3Pp79o2VcNgXAxc3z/DAkEA32Hz1kPS2VpxyHsMUtgzJ3T5zr8dcJu0RcDq3jPzfVopos6di49Sy5NTJC5syerJ4BdbEaXzLoJx/JbjshMvawJBAJHKTqo2hu2iF4iMk5XtXmGHfU5M8trlWJtnYHDozE1JhpQB5ePfBrX8dHnCVPrlAr8UImtsZA4CbeJUhcJ2/xkCQQDccAwxOFL9PLymK49YvZOVb2EJPh3uPykh4KOlzTyOSghmamCcFT6OOH9GaC3hADphUosDGnGlRwL3UWu3EimrAkBmcBbkPqNWYlvP8QMG4oD7V6d2PGmOCIjSbS1C3u+FRW4d60YBZso4R6e9TIPwjQbYH/FvSnM9x7TdMQKrmVzZ";
|
||||
const TEST_BOC_RSA_PUBLIC_KEY_STR = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCCHZmX7xJMAcztH3iqTYjfft5gGBRTNYNP9Vzfclilg9j+Yyr+YELo+TzEA30cl0zd7G1R1C9nUdL1GU9p5NnbvqGRgK0N32gnd7v9DS+onYvqhv2shLfLjUuW96+uRaCHJc2evjmbzNWc32ahc6JHz/79/4Z5zCgMllsiNMknjwIDAQAB";
|
||||
const PROD_GY_RSA_PUBLIC_KEY_STR = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCpC9n13422gtdpyaHMdCPLxNE6NT22cWzl0hK2tOhyAzKliZ4eFatDPd3XhTIHa3cXsfwcYzMONRdwG30dgup+jQiOuryWkKeGVun4BpOqpgIsrVO36aqMvd/6cqA/5XjZ7O0+HAMDRKLEmvU2JfKUa/d7YOK7cADP+eyFjcssGQIDAQAB";
|
||||
const PROD_GY_RSA_PRIVATE_KEY_STR = "MIICXgIBAAKBgQCpC9n13422gtdpyaHMdCPLxNE6NT22cWzl0hK2tOhyAzKliZ4eFatDPd3XhTIHa3cXsfwcYzMONRdwG30dgup+jQiOuryWkKeGVun4BpOqpgIsrVO36aqMvd/6cqA/5XjZ7O0+HAMDRKLEmvU2JfKUa/d7YOK7cADP+eyFjcssGQIDAQABAoGBAJDFg46cO8M4Xr9MXPK57AYQspbFDer3TKmttTUfzYoGzxMRvoZJTHizvQ9cFLJiCIYUebLeCdV7Bm2OPSJPAf6l298BSWuoi5sItjxac6n3mknTMDb8DQxBvYmNdTLyNZyDm9P9PzyaovAYFtu+H9yEu77NzniPgdIrT0VHnOYBAkEA4UBfaTG2/nHUKIx2pjlaT3K1KwOgkq2nE4eq6wiiuf2+xvsedhvOwPY65Di1BfEqoVVO2DB5qKHe2LRVeRy/uQJBAMAfVe2WTvR4QSUVAV5h3X3Gsi+uvmMAeMATRq0sPgR6+ZvlX1gqiamrqwFxo1/5HjzYCMkcxtiqQeJ13Hh4P2ECQQCMRXYlIByBH4mrJq3MnfKrfxdrDfs03IcrFlVNwDb19BqV91Pk4TRD3hKWhOnWJXUSuvk6kBVy+jq4YLTJkymhAkAs5WW8LrrmsE9w7fay6qXK5arwL6K4Gf0dzaNfho47l81K3BAq103yQ3aj0L2ACQRC7a0n6jyhly/sTuSlllwhAkEAgWXIDYVFjwfkRqIhCUzaTzO4X7g1oCXrVxS0F9YFWFzhGf44QCk1Au3fWbUWm0tj0t37N+uAMLrv+y6vm8n6pw==";
|
||||
const PROD_BOC_RSA_PUBLIC_KEY_STR = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCjEv+5pGVlqRN/UxeMrZIBJtyCQEk/QuRLQUoHHO05Jwf3TD0HcWVjBn/apYZlcJFs0Bk9n0VgbYHSuACMv7n5MvcFfC0vuRGOOcdwDkrpJhwBDiMWMUiFP1q1jAhZJ//WVmFEKeG0R6iAao0ZH9d6B1jNHTTgxWE1K9oZGwPMwwIDAQAB";
|
||||
|
||||
|
||||
|
||||
private $bochost;
|
||||
private $GY_AES_KEY;
|
||||
|
||||
private $GY_RSA_PUBLIC_KEY_STR;
|
||||
private $GY_RSA_PRIVATE_KEY_STR;
|
||||
private $BOC_RSA_PUBLIC_KEY_STR;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
$this->bochost = Env::get('bocapi.boc_host');
|
||||
$this->GY_AES_KEY = Env::get('bocapi.GY_AES_KEY');
|
||||
$key_env = Env::get('bocapi.KEY_ENV');
|
||||
if ( $key_env == "TEST") {
|
||||
$this->GY_RSA_PUBLIC_KEY_STR = self::TEST_GY_RSA_PUBLIC_KEY_STR;
|
||||
$this->GY_RSA_PRIVATE_KEY_STR = self::TEST_GY_RSA_PRIVATE_KEY_STR;
|
||||
$this->BOC_RSA_PUBLIC_KEY_STR = self::TEST_BOC_RSA_PUBLIC_KEY_STR;
|
||||
} else {
|
||||
$this->GY_RSA_PUBLIC_KEY_STR = self::PROD_GY_RSA_PUBLIC_KEY_STR;
|
||||
$this->GY_RSA_PRIVATE_KEY_STR = self::PROD_GY_RSA_PRIVATE_KEY_STR;
|
||||
$this->BOC_RSA_PUBLIC_KEY_STR = self::PROD_BOC_RSA_PUBLIC_KEY_STR;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function getGYRSAPRIVATEKEY() {
|
||||
return "-----BEGIN RSA PRIVATE KEY-----\n" . wordwrap($this->GY_RSA_PRIVATE_KEY_STR, 64, "\n", true) . "\n-----END RSA PRIVATE KEY-----";
|
||||
}
|
||||
private function getGYRSAPUBLICKEY() {
|
||||
return "-----BEGIN PUBLIC KEY-----\n" . wordwrap($this->GY_RSA_PUBLIC_KEY_STR, 64, "\n", true) . "\n-----END PUBLIC KEY-----";
|
||||
}
|
||||
|
||||
private function getBOCRSAPUBLICKEY() {
|
||||
return "-----BEGIN PUBLIC KEY-----\n" . wordwrap($this->BOC_RSA_PUBLIC_KEY_STR, 64, "\n", true) . "\n-----END PUBLIC KEY-----";
|
||||
}
|
||||
public function decodeFromBOC($cipherkey,$ciphertext,$sign) {
|
||||
$aeskey = $this->getBOCAESKEY($cipherkey);
|
||||
$ciphertext_decode = $this->aesDecode($aeskey,$ciphertext);
|
||||
return $ciphertext_decode;
|
||||
}
|
||||
|
||||
public function encryptGYAESKEY() {
|
||||
$encrypted_aes_key = "";
|
||||
openssl_public_encrypt($this->GY_AES_KEY, $encrypted_aes_key, $this->getBOCRSAPUBLICKEY());
|
||||
$cipherkey = base64_encode($encrypted_aes_key);
|
||||
return $cipherkey;
|
||||
}
|
||||
public function encodeForBOC($data){
|
||||
$cipherkey = $this->encryptGYAESKEY();
|
||||
$aes = new Aes($this->GY_AES_KEY);
|
||||
$ciphertext = $aes->aesEn(json_encode($data));
|
||||
|
||||
$sign =$this->getGYSign($ciphertext);
|
||||
|
||||
$postData = array(
|
||||
'ciphertext' => $ciphertext,
|
||||
'cipherkey' =>$cipherkey,
|
||||
'sign' =>$sign,
|
||||
'companyCode' => '20'
|
||||
);
|
||||
return $postData;
|
||||
}
|
||||
|
||||
|
||||
public function getURLPreResult() {
|
||||
return $this->bochost . self::PRE_ESTIMATE_API;
|
||||
}
|
||||
|
||||
public function getURLOfficialResult() {
|
||||
return $this->bochost . self::OFFICIAL_ESTIMATE_API;
|
||||
}
|
||||
|
||||
public function sendPreResult($data) {
|
||||
$url = $this->getURLPreResult();
|
||||
return $this->sendToBOC($url,$data);
|
||||
}
|
||||
|
||||
public function sendOfficialResult($data) {
|
||||
$url = $this->getURLOfficialResult();
|
||||
return $this->sendToBOC($url,$data);
|
||||
}
|
||||
|
||||
/**
|
||||
*发送给银行
|
||||
*/
|
||||
public function sendToBOC($url,$data) {
|
||||
$postData = $this->encodeForBOC($data);
|
||||
Log::debug("--------------------sendToBOC start -------------------");
|
||||
Log::debug($data);
|
||||
Log::debug("--------------------after encode -------------------");
|
||||
Log::debug($url);
|
||||
Log::debug($postData);
|
||||
$arr_header[] = "Content-Type: application/json; charset=utf-8";
|
||||
$httpreturn = $this->http_post($url,$postData,false,60,$arr_header);
|
||||
Log::debug($httpreturn);
|
||||
Log::debug("--------------------sendToBOC end -------------------");
|
||||
return $httpreturn;
|
||||
}
|
||||
|
||||
public function responseToBOC($code,$msg,$data) {
|
||||
$res['code'] = $code;
|
||||
$res['message'] = $msg;
|
||||
$res['data'] = $data;
|
||||
$forBOC = $this->encodeForBOC($res);
|
||||
$response = Response::create($forBOC, 'json');
|
||||
return $response;
|
||||
}
|
||||
public function getGYSign($ciphertext) {
|
||||
return md5($this->BOC_RSA_PUBLIC_KEY_STR . $ciphertext);
|
||||
}
|
||||
public function getBOCAESKEY($cipherkey) {
|
||||
$private_key = openssl_pkey_get_private($this->getGYRSAPRIVATEKEY());
|
||||
if (!$private_key) {
|
||||
throw new Exception('私钥不可用');
|
||||
}
|
||||
$decrypted = "";
|
||||
$return_de = openssl_private_decrypt(base64_decode($cipherkey), $decrypted, $private_key);
|
||||
if (!$return_de) {
|
||||
throw new Exception('解密失败,请检查传入RSA秘钥');
|
||||
}
|
||||
return $decrypted;
|
||||
}
|
||||
|
||||
public function aesDecode($aeskey,$ciphertext) {
|
||||
$aes = new Aes($aeskey);
|
||||
$ciphertext_decode = $aes->aesDe($ciphertext);
|
||||
$result = json_decode($ciphertext_decode,true);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* GET 请求
|
||||
* @param string $url
|
||||
*/
|
||||
public function http_get($url,$param,$arr_header=array()){
|
||||
$oCurl = curl_init();
|
||||
if (is_string($param)) {
|
||||
$strPOST = $param;
|
||||
} else {
|
||||
$aPOST = array();
|
||||
foreach ($param as $key => $val) {
|
||||
$aPOST[] = $key . "=" . $val;
|
||||
}
|
||||
$strPOST = join("&", $aPOST);
|
||||
}
|
||||
$url = $url."?".$strPOST;
|
||||
if (stripos($url, "https://") !== false) {
|
||||
curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
|
||||
}
|
||||
curl_setopt($oCurl, CURLOPT_URL, $url);
|
||||
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1);
|
||||
if(!empty($arr_header)){
|
||||
$arr_header[] = "Content-Type: application/json; charset=utf-8";
|
||||
}
|
||||
curl_setopt($oCurl, CURLOPT_HTTPHEADER, $arr_header);
|
||||
|
||||
$sContent = curl_exec($oCurl);
|
||||
if (curl_errno($oCurl)){
|
||||
throw new Exception(curl_error($oCurl),0);
|
||||
}else{
|
||||
$httpStatusCode = curl_getinfo($oCurl, CURLINFO_HTTP_CODE);
|
||||
if (200 !== $httpStatusCode){
|
||||
|
||||
throw new Exception($arr_header[1],$httpStatusCode);
|
||||
}
|
||||
}
|
||||
curl_close($oCurl);
|
||||
return $sContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* POST 请求
|
||||
* @param string $url
|
||||
* @param array $param
|
||||
* @param boolean $post_file 是否文件上传
|
||||
* @param boolean $timeout 超时时间,单位秒
|
||||
* @param boolean $arr_header http请求头
|
||||
* @return string content
|
||||
*/
|
||||
public function http_post($url, $param, $post_file = false, $timeout = 30,$arr_header=array()){
|
||||
$ch = curl_init();
|
||||
|
||||
curl_setopt_array($ch, array(
|
||||
// 不直接输出,返回到变量
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
// 设置超时为60s,防止机器被大量超时请求卡死
|
||||
CURLOPT_TIMEOUT => $timeout
|
||||
));
|
||||
// 支持POST请求
|
||||
if (!empty($param)) {
|
||||
curl_setopt_array($ch, array(
|
||||
CURLOPT_POST => true,
|
||||
// 设置POST参数
|
||||
CURLOPT_POSTFIELDS => json_encode($param)
|
||||
));
|
||||
}
|
||||
/*
|
||||
if (is_string($param) || $post_file) {
|
||||
$strPOST = $param;
|
||||
} else {
|
||||
$aPOST = array();
|
||||
foreach ($param as $key => $val) {
|
||||
$aPOST[] = $key . "=" . $val;
|
||||
}
|
||||
$strPOST = join("&", $aPOST);
|
||||
}
|
||||
*/
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $arr_header);
|
||||
|
||||
$sContent = curl_exec($ch);
|
||||
$aStatus = curl_getinfo($ch);
|
||||
curl_close($ch);
|
||||
|
||||
if (intval($aStatus["http_code"]) == 200) {
|
||||
return $sContent;
|
||||
} else {
|
||||
return $aStatus;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DELETE 请求
|
||||
* @param string $url
|
||||
* @param array $param
|
||||
* @param boolean $user_name AUTH账号
|
||||
* @param boolean $password AUTH密码
|
||||
* @return string content
|
||||
*/
|
||||
function http_delete($url,$param,$user_name,$password) {
|
||||
$oCurl = curl_init();
|
||||
|
||||
if (is_string($param)) {
|
||||
$strPOST = $param;
|
||||
} else {
|
||||
$aPOST = array();
|
||||
foreach ($param as $key => $val) {
|
||||
$aPOST[] = $key . "=" . $val;
|
||||
}
|
||||
$strPOST = join("&", $aPOST);
|
||||
}
|
||||
$url = $url."?".$strPOST;
|
||||
|
||||
curl_setopt($oCurl, CURLOPT_URL, $url);
|
||||
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($oCurl, CURLOPT_CUSTOMREQUEST, 'DELETE');
|
||||
|
||||
//设置头
|
||||
curl_setopt($oCurl, CURLOPT_USERPWD, "{$user_name}:{$password}");
|
||||
curl_setopt($oCurl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36');
|
||||
|
||||
curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, false);//SSL认证。
|
||||
$sContent = curl_exec($oCurl);
|
||||
$aStatus = curl_getinfo($oCurl);
|
||||
|
||||
curl_close($oCurl);
|
||||
|
||||
if (intval($aStatus["http_code"]) == 200) {
|
||||
return $sContent;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////接口说明///////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* 银行向评估公司推送评估资料,发起预评估申请
|
||||
* https://app-host:30012/V2/preApply
|
||||
* @Author llz
|
||||
* @DateTime 2022-11-18
|
||||
* @version 1.0
|
||||
* @param ciphertext 返回结果的json字符串用AES加密,转base64。UrlBase64(AES(tojson(返回结果)))
|
||||
* @param sign MD5(SALT+ciphertext)
|
||||
* @param cipherkey 用RSA公钥对AES的秘钥进行加密,转base64。UrlBase64(RSA(AES秘钥))
|
||||
|
||||
* @return string 查询结果json字符串
|
||||
*/
|
||||
public function preApply($data){
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 评估公司将预评估结果推送到银行
|
||||
* https://app-host:30012/estimate/receivePreResult
|
||||
* @Author llz
|
||||
* @DateTime 2018-10-08
|
||||
* @version 1.0
|
||||
* @param ciphertext 返回结果的json字符串用AES加密,转base64。UrlBase64(AES(tojson(返回结果)))
|
||||
* @param sign MD5(SALT+ciphertext)
|
||||
* @param cipherkey 用RSA公钥对AES的秘钥进行加密,转base64。UrlBase64(RSA(AES秘钥))
|
||||
* @param companyCode 评估公司编码
|
||||
* @return string 查询结果json字符串
|
||||
*/
|
||||
public function preResult($data){
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 银行调用该接口通知评估公司生成正式评估报告
|
||||
* https://app-host:30012/V2/applyOfficial
|
||||
* @Author llz
|
||||
* @DateTime 2022-11-18
|
||||
* @version 1.0
|
||||
* @param ciphertext 返回结果的json字符串用AES加密,转base64。UrlBase64(AES(tojson(返回结果)))
|
||||
* @param sign MD5(SALT+ciphertext)
|
||||
* @param cipherkey 用RSA公钥对AES的秘钥进行加密,转base64。UrlBase64(RSA(AES秘钥))
|
||||
|
||||
* @return string 查询结果json字符串
|
||||
*/
|
||||
public function applyOfficial($data){
|
||||
}
|
||||
|
||||
/**
|
||||
* 评估公司将正式评估结果推送到银行
|
||||
* https://app-host:30012/estimate/receiveOff
|
||||
* @Author llz
|
||||
* @DateTime 2018-10-08
|
||||
* @version 1.0
|
||||
* @param ciphertext 返回结果的json字符串用AES加密,转base64。UrlBase64(AES(tojson(返回结果)))
|
||||
* @param sign MD5(SALT+ciphertext)
|
||||
* @param cipherkey 用RSA公钥对AES的秘钥进行加密,转base64。UrlBase64(RSA(AES秘钥))
|
||||
* @param companyCode 评估公司编码
|
||||
* @return string 查询结果json字符串
|
||||
*/
|
||||
public function officialResult($data){
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
417
pgserver/application/lib/CEBApi.php
Normal file
417
pgserver/application/lib/CEBApi.php
Normal file
@@ -0,0 +1,417 @@
|
||||
<?php
|
||||
|
||||
namespace app\lib;
|
||||
|
||||
use app\util\Tools;
|
||||
use app\util\ReturnCode;
|
||||
use think\facade\Response;
|
||||
use think\facade\Env;
|
||||
use think\Exception;
|
||||
use app\util\Aes;
|
||||
use app\model\CebReportResult;
|
||||
use think\facade\Log;
|
||||
|
||||
/**
|
||||
* 光大银行系统接口
|
||||
*/
|
||||
class CEBApi
|
||||
{
|
||||
//光大银行接收询价结果接口
|
||||
const ESZ004_API = '/webapi/Cebbank/ESZ004/returnESZ004Info';
|
||||
const ESZ009_API = '/webapi/Cebbank/ESZ009/returnESZ009Info';
|
||||
const ESZ011_API = '/webapi/Cebbank/ESZ011/returnESZ011Info';
|
||||
const ESZ006_API = '/webapi/Cebbank/ESZ006/returnESZ006Info'; // 2.2.2 评估报告结果返回申请
|
||||
|
||||
//接收正式评估结果接口
|
||||
const OFFICIAL_ESTIMATE_API = '/jkpt/pggsApi/estimate/receiveOff';
|
||||
|
||||
private $cebhost;
|
||||
private $ftp_server = "";
|
||||
private $ftp_port = 0;
|
||||
private $ftp_user_name = "";
|
||||
private $ftp_user_pass = "";
|
||||
|
||||
public function __construct(){
|
||||
|
||||
$this->ftp_server = Env::get('cebapi.ceb_ftp_host');
|
||||
|
||||
|
||||
|
||||
$key_env = Env::get('cebapi.KEY_ENV');
|
||||
if ( $key_env == "TEST") {
|
||||
$this->cebhost = Env::get('cebapi.ceb_test_host');
|
||||
$this->ftp_port = Env::get('cebapi.ceb_test_ftp_port');
|
||||
} else { // PROD
|
||||
$this->cebhost = Env::get('cebapi.ceb_prop_host');
|
||||
$this->ftp_port = Env::get('cebapi.ceb_prod_ftp_port');
|
||||
}
|
||||
|
||||
$this->ftp_user_name = Env::get('cebapi.ftp_user_name');
|
||||
$this->ftp_user_pass = Env::get('cebapi.ftp_user_pass');
|
||||
}
|
||||
|
||||
public function getFileFromFtp($remotefile) {
|
||||
$ret['code'] = 1;
|
||||
$ret['data'] = "";
|
||||
try
|
||||
{
|
||||
$sftp = new SFTPConnection($this->ftp_server, $this->ftp_port);
|
||||
$sftp->login($this->ftp_user_name, $this->ftp_user_pass);
|
||||
$fileData = $sftp->getFile( $remotefile);
|
||||
$ret['data'] = $fileData;
|
||||
return $ret;
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
$ret['code'] = -1;
|
||||
$ret['data'] = $e->getMessage() ;
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
public function sendFileToFtp($localfile, $path, $remotefile) {
|
||||
|
||||
try
|
||||
{
|
||||
$sftp = new SFTPConnection($this->ftp_server, $this->ftp_port);
|
||||
$sftp->login($this->ftp_user_name, $this->ftp_user_pass);
|
||||
$sftp->uploadFile($localfile, $path, $remotefile);
|
||||
Log::debug('upload to ftp:' . $remotefile);
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
echo $e->getMessage() . "\n";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// 2.2.2 评估报告结果返回申请
|
||||
public function getURLESZ006(){
|
||||
return $this->cebhost . self::ESZ006_API;
|
||||
}
|
||||
|
||||
public function getURLESZ004() {
|
||||
return $this->cebhost . self::ESZ004_API;
|
||||
}
|
||||
|
||||
public function getURLESZ011() {
|
||||
return $this->cebhost . self::ESZ011_API;
|
||||
}
|
||||
public function getURLESZ009() {
|
||||
return $this->cebhost . self::ESZ009_API;
|
||||
}
|
||||
|
||||
public function sendInquiryResult($data) {
|
||||
$url = $this->getURLESZ004();
|
||||
$cebData['businessNo'] = $data['business_no'] ;
|
||||
$cebData['companyCode'] = $data['company_code'] ;
|
||||
$cebData['businessType'] = $data['business_type'] ;
|
||||
if($data['business_type'] == "01") { //贷前询价
|
||||
$cebData['unitPriceDetail'] = "0";
|
||||
$cebData['guidedUnitPriceDetail'] = "0";
|
||||
}else if ($data['business_type'] == "02"){ //贷中询价
|
||||
$cebData['unitPriceDetail'] = $data['unitPriceDetail'];
|
||||
$cebData['guidedUnitPriceDetail'] = $data['guidedUnitPriceDetail'];
|
||||
}
|
||||
$cebData['certificateNo'] = $data['certificate_no'] ;
|
||||
$cebData['estimateDealNo'] = $data['estimate_deal_no'];
|
||||
$cebData['totalPrice'] = $data['eva_total_value'] ;
|
||||
$cebData['chargeAmt'] = $data['charge_amt'] ;
|
||||
$cebData['guidedPrice'] = $data['guide_price'] ;
|
||||
$cebData['netWorth'] = $data['eva_net_value'] ;
|
||||
$cebData['evaluatorName'] = $data['evaluator_name'] ;
|
||||
$cebData['telephoneNumber'] = $data['telephone_number'] ;
|
||||
$cebData['estimateTime'] = $data['estimate_time'] ;
|
||||
$cebData['status'] = $data['status'] ;
|
||||
$cebData['field1'] = '' ;
|
||||
$cebData['field2'] = '' ;
|
||||
if(isset($data['reason'])) {
|
||||
$cebData['field3'] = $data['reason'];
|
||||
}else {
|
||||
$cebData['field3'] = '';
|
||||
}
|
||||
return $this->sendToCEB($url,$cebData,"ESZ004");
|
||||
}
|
||||
|
||||
public function sendReevaluateResult($data) {
|
||||
$url = $this->getURLESZ011();
|
||||
|
||||
$cebData['businessNo'] = $data['businessNo'] ;
|
||||
$cebData['companyCode'] = $data['companyCode'] ;
|
||||
$cebData['estimateDealNo'] = $data['estimateDealNo'] ;
|
||||
$cebData['reevaluatedFileName'] = $data['reevaluatedFileName'] ;
|
||||
$cebData['reevaluatedFileEnd'] = $data['reevaluatedFileEnd'] ;
|
||||
$cebData['reevaluatedFilePath'] = $data['reevaluatedFilePath'] ;
|
||||
$cebData['status'] = $data['status'] ;
|
||||
|
||||
|
||||
$cebData['estimateTime'] = $data['estimateTime'] ;
|
||||
|
||||
$cebData['field1'] = '' ;
|
||||
$cebData['field2'] = '' ;
|
||||
if(isset($data['reason'])) {
|
||||
$cebData['field3'] = $data['reason'];
|
||||
}else {
|
||||
$cebData['field3'] = '';
|
||||
}
|
||||
|
||||
return $this->sendToCEB($url,$cebData,"ESZ011");
|
||||
}
|
||||
/**
|
||||
* ESZ006 预评估和正式报告回复 function
|
||||
*
|
||||
* @param [type] $data
|
||||
* @return void
|
||||
*/
|
||||
public function sendReportResult($data) {
|
||||
$url = $this->getURLESZ006();
|
||||
$cebData['businessNo'] = $data['business_no'] ;
|
||||
$cebData['companyCode'] = $data['company_code'] ;
|
||||
$cebData['businessType'] = $data['business_type'] ;
|
||||
$cebData['returnReportType'] = $data['return_report_type'] ;
|
||||
$cebData['unitPrice'] = $data['eva_unit_price'] ;
|
||||
$cebData['estimateDealNo'] = $data['estimate_deal_no']; //已有预估编号,不需要再加公司编码做前缀
|
||||
$cebData['totalPrice'] = $data['eva_total_value'] ;
|
||||
$cebData['totalTax'] = $data['total_tax'] ;
|
||||
$cebData['detailTax'] = $data['detail_tax'];
|
||||
$cebData['chargeAmt'] = $data['charge_amt'] ;
|
||||
$cebData['guidedPrice'] = $data['guide_price'] ;
|
||||
$cebData['netWorth'] = $data['eva_net_value'] ;
|
||||
$cebData['estimateReportName'] = $data['estimate_report_name'] ;
|
||||
$cebData['estimateReportEnd'] = $data['estimate_report_end'] ;
|
||||
$cebData['estimateReportPath'] = $data['estimate_report_path'] ;
|
||||
|
||||
if( $data['business_type'] == CebReportResult::BUSINESS_TYPE_REPORT )
|
||||
{
|
||||
$cebData['mortgagor1'] = $data['mortgagor1'] ;
|
||||
$cebData['mortgagor2'] = $data['mortgagor2'] ;
|
||||
$cebData['mortgagor3'] = $data['mortgagor3'] ;
|
||||
$cebData['mortgagor4'] = $data['mortgagor4'] ;
|
||||
$cebData['mortgagor5'] = $data['mortgagor5'] ;
|
||||
$cebData['mortgagor6'] = $data['mortgagor6'] ;
|
||||
$cebData['field1'] = $data['field1'] ;
|
||||
} else {
|
||||
$cebData['mortgagor1'] = "" ;
|
||||
$cebData['mortgagor2'] = "" ;
|
||||
$cebData['mortgagor3'] = "" ;
|
||||
$cebData['mortgagor4'] = "" ;
|
||||
$cebData['mortgagor5'] = "" ;
|
||||
$cebData['mortgagor6'] = "" ;
|
||||
$cebData['field1'] = '';
|
||||
}
|
||||
|
||||
|
||||
|
||||
$cebData['resultStatus'] = $data['result_status'] ;
|
||||
$cebData['reason'] = $data['reason'] ;
|
||||
|
||||
$cebData['field2'] = '' ;
|
||||
$cebData['field3'] = '' ;
|
||||
$cebData['estimateTime'] = $data['estimate_time'] ;
|
||||
|
||||
|
||||
|
||||
return $this->sendToCEB($url,$cebData,"ESZ006");
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function sendCheckResult($data) {
|
||||
$url = $this->getURLESZ009();
|
||||
$cebData['businessNo'] = $data['business_no'] ;
|
||||
$cebData['companyCode'] = $data['company_code'] ;
|
||||
$cebData['estimateDealNo'] = $data['estimate_deal_no'];
|
||||
$cebData['checkTotalPrice'] = $data['check_total_price'] ;
|
||||
$cebData['checkNetWorth'] = $data['check_net_worth'] ;
|
||||
$cebData['checkChargeAmt'] = $data['check_charge_amt'] ;
|
||||
|
||||
$cebData['checkTime'] = $data['check_time'] ;
|
||||
$cebData['checkStatus'] = $data['check_status'] ;
|
||||
$cebData['field1'] = '' ;
|
||||
$cebData['field2'] = '' ;
|
||||
if(isset($data['reason'])){
|
||||
$cebData['field3'] = $data['reason'] ;
|
||||
}else{
|
||||
$cebData['field3'] = '' ;
|
||||
}
|
||||
|
||||
|
||||
return $this->sendToCEB($url,$cebData,"ESZ009");
|
||||
}
|
||||
|
||||
/**
|
||||
*发送给银行
|
||||
*/
|
||||
public function sendToCEB($url,$data,$tranCode) {
|
||||
Log::debug("--------------------发送给光大银行-------------------");
|
||||
Log::debug($url);
|
||||
Log::debug($data);
|
||||
//$arr_header['Content-Type'] = "application/json; charset=utf-8";
|
||||
//$arr_header['Cebsz'] ="oemp";
|
||||
//$arr_header['tranCode'] =$tranCode;
|
||||
$arr_header = array(
|
||||
"Content-Type: application/json; charset=utf-8",
|
||||
"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36",
|
||||
"Cebsz:oemp",
|
||||
"tranCode:" . $tranCode . ""
|
||||
);
|
||||
|
||||
$httpreturn = $this->http_post($url,$data,false,60,$arr_header);
|
||||
Log::debug("------------------Http post 返回-------------");
|
||||
try{
|
||||
Log::debug($httpreturn);
|
||||
}catch(Exception $e){
|
||||
Log::warning($e->getMessage());
|
||||
}
|
||||
return $httpreturn;
|
||||
}
|
||||
|
||||
public function responseToCEB($code,$msg,$data) {
|
||||
$res['code'] = $code;
|
||||
$res['message'] = $msg;
|
||||
$res['data'] = $data;
|
||||
|
||||
$response = Response::create($res, 'json');
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* GET 请求
|
||||
* @param string $url
|
||||
*/
|
||||
public function http_get($url,$param,$arr_header=array()){
|
||||
$oCurl = curl_init();
|
||||
if (is_string($param)) {
|
||||
$strPOST = $param;
|
||||
} else {
|
||||
$aPOST = array();
|
||||
foreach ($param as $key => $val) {
|
||||
$aPOST[] = $key . "=" . $val;
|
||||
}
|
||||
$strPOST = join("&", $aPOST);
|
||||
}
|
||||
$url = $url."?".$strPOST;
|
||||
if (stripos($url, "https://") !== false) {
|
||||
curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
|
||||
}
|
||||
curl_setopt($oCurl, CURLOPT_URL, $url);
|
||||
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1);
|
||||
if(!empty($arr_header)){
|
||||
$arr_header[] = "Content-Type: application/json; charset=utf-8";
|
||||
}
|
||||
curl_setopt($oCurl, CURLOPT_HTTPHEADER, $arr_header);
|
||||
|
||||
$sContent = curl_exec($oCurl);
|
||||
if (curl_errno($oCurl)){
|
||||
throw new Exception(curl_error($oCurl),0);
|
||||
}else{
|
||||
$httpStatusCode = curl_getinfo($oCurl, CURLINFO_HTTP_CODE);
|
||||
if (200 !== $httpStatusCode){
|
||||
|
||||
throw new Exception($arr_header[1],$httpStatusCode);
|
||||
}
|
||||
}
|
||||
curl_close($oCurl);
|
||||
return $sContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* POST 请求
|
||||
* @param string $url
|
||||
* @param array $param
|
||||
* @param boolean $post_file 是否文件上传
|
||||
* @param boolean $timeout 超时时间,单位秒
|
||||
* @param boolean $arr_header http请求头
|
||||
* @return string content
|
||||
*/
|
||||
public function http_post($url, $param, $post_file = false, $timeout = 30,$arr_header=array()){
|
||||
$ch = curl_init();
|
||||
|
||||
curl_setopt_array($ch, array(
|
||||
// 不直接输出,返回到变量
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
// 设置超时为60s,防止机器被大量超时请求卡死
|
||||
CURLOPT_TIMEOUT => $timeout
|
||||
));
|
||||
// 支持POST请求
|
||||
if (!empty($param)) {
|
||||
curl_setopt_array($ch, array(
|
||||
CURLOPT_POST => true,
|
||||
// 设置POST参数
|
||||
CURLOPT_POSTFIELDS => json_encode($param)
|
||||
));
|
||||
}
|
||||
/*
|
||||
if (is_string($param) || $post_file) {
|
||||
$strPOST = $param;
|
||||
} else {
|
||||
$aPOST = array();
|
||||
foreach ($param as $key => $val) {
|
||||
$aPOST[] = $key . "=" . $val;
|
||||
}
|
||||
$strPOST = join("&", $aPOST);
|
||||
}
|
||||
*/
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $arr_header);
|
||||
|
||||
$sContent = curl_exec($ch);
|
||||
$aStatus = curl_getinfo($ch);
|
||||
curl_close($ch);
|
||||
|
||||
if (intval($aStatus["http_code"]) == 200) {
|
||||
return $sContent;
|
||||
} else {
|
||||
return $aStatus;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DELETE 请求
|
||||
* @param string $url
|
||||
* @param array $param
|
||||
* @param boolean $user_name AUTH账号
|
||||
* @param boolean $password AUTH密码
|
||||
* @return string content
|
||||
*/
|
||||
function http_delete($url,$param,$user_name,$password) {
|
||||
$oCurl = curl_init();
|
||||
|
||||
if (is_string($param)) {
|
||||
$strPOST = $param;
|
||||
} else {
|
||||
$aPOST = array();
|
||||
foreach ($param as $key => $val) {
|
||||
$aPOST[] = $key . "=" . $val;
|
||||
}
|
||||
$strPOST = join("&", $aPOST);
|
||||
}
|
||||
$url = $url."?".$strPOST;
|
||||
|
||||
curl_setopt($oCurl, CURLOPT_URL, $url);
|
||||
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($oCurl, CURLOPT_CUSTOMREQUEST, 'DELETE');
|
||||
|
||||
//设置头
|
||||
curl_setopt($oCurl, CURLOPT_USERPWD, "{$user_name}:{$password}");
|
||||
curl_setopt($oCurl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36');
|
||||
|
||||
curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, false);//SSL认证。
|
||||
$sContent = curl_exec($oCurl);
|
||||
$aStatus = curl_getinfo($oCurl);
|
||||
|
||||
curl_close($oCurl);
|
||||
|
||||
if (intval($aStatus["http_code"]) == 200) {
|
||||
return $sContent;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
80
pgserver/application/lib/DesCrypto.php
Normal file
80
pgserver/application/lib/DesCrypto.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
namespace app\lib;
|
||||
class DesCrypto
|
||||
{
|
||||
private $key;
|
||||
private $iv;
|
||||
|
||||
/**
|
||||
* 构造函数(集成固定密钥和向量)
|
||||
*/
|
||||
public function __construct($key, $iv)
|
||||
{
|
||||
// 使用您提供的固定密钥
|
||||
$this->key = $this->padToLength($key, 8);
|
||||
// 使用您提供的固定向量
|
||||
$this->iv = $this->padToLength($iv, 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* DES加密(CBC模式 + PKCS5Padding)
|
||||
* @param string $data 待加密数据
|
||||
* @return string Base64编码的加密结果
|
||||
*/
|
||||
public function encrypt($data)
|
||||
{
|
||||
// 添加PKCS5填充
|
||||
$blockSize = 8;
|
||||
$pad = $blockSize - (strlen($data) % $blockSize);
|
||||
$data .= str_repeat(chr($pad), $pad);
|
||||
|
||||
// 执行加密
|
||||
$encrypted = openssl_encrypt(
|
||||
$data,
|
||||
'DES-CBC',
|
||||
$this->key,
|
||||
OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING,
|
||||
$this->iv
|
||||
);
|
||||
|
||||
return base64_encode($encrypted);
|
||||
}
|
||||
|
||||
/**
|
||||
* DES解密
|
||||
* @param string $base64Data Base64编码的加密数据
|
||||
* @return string 解密后的原始数据
|
||||
*/
|
||||
public function decrypt($base64Data)
|
||||
{
|
||||
$encrypted = base64_decode($base64Data);
|
||||
|
||||
// 执行解密
|
||||
$decrypted = openssl_decrypt(
|
||||
$encrypted,
|
||||
'DES-CBC',
|
||||
$this->key,
|
||||
OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING,
|
||||
$this->iv
|
||||
);
|
||||
|
||||
// 移除PKCS5填充
|
||||
$pad = ord($decrypted[strlen($decrypted) - 1]);
|
||||
return substr($decrypted, 0, -$pad);
|
||||
}
|
||||
|
||||
/**
|
||||
* 辅助方法:填充/截断字符串到指定长度
|
||||
* @param string $str 输入字符串
|
||||
* @param int $length 目标长度
|
||||
* @return string 处理后的字符串
|
||||
*/
|
||||
private function padToLength($str, $length)
|
||||
{
|
||||
if (strlen($str) > $length) {
|
||||
return substr($str, 0, $length);
|
||||
}
|
||||
return str_pad($str, $length, "\0");
|
||||
}
|
||||
}
|
||||
121
pgserver/application/lib/FbbService.php
Normal file
121
pgserver/application/lib/FbbService.php
Normal file
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* FBB A 服务类调用公共组件
|
||||
*
|
||||
*/
|
||||
|
||||
namespace app\lib;
|
||||
|
||||
use app\util\Tools;
|
||||
use app\util\ReturnCode;
|
||||
use think\facade\Env;
|
||||
|
||||
/**
|
||||
* Description of FbbService
|
||||
*
|
||||
* @author ZJQ
|
||||
*/
|
||||
class FbbService {
|
||||
|
||||
//调用信息
|
||||
const API_KEY = 'UrFNPjTkOleqX7T2';
|
||||
const API_SECRET = 'omJJDkfqOpXXicK08suWvVLXKx4kX1eg';
|
||||
//调用接口
|
||||
const PARENT_INFO = 'Message/addAppPgMessage'; //调用房帮帮A消息推送
|
||||
|
||||
private $appkey;
|
||||
private $secret;
|
||||
private $sign;
|
||||
private $timestamp;
|
||||
|
||||
public function __construct() {
|
||||
$this->appkey = self::API_KEY;
|
||||
$this->secret = self::API_SECRET;
|
||||
$this->timestamp = time();
|
||||
$this->sign = md5($this->appkey . $this->secret . $this->timestamp);
|
||||
}
|
||||
|
||||
public function addAppBsMessage($params) {
|
||||
$result = $this->http_post(Env::get('appConfig.app_api') . self::PARENT_INFO, $this->getData($params));
|
||||
if ($result) {
|
||||
$json = json_decode($result, true);
|
||||
return $json;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* 组装数据 */
|
||||
|
||||
private function getData($params) {
|
||||
$data['appkey'] = $this->appkey;
|
||||
$data['sign'] = $this->sign;
|
||||
$data['timestamp'] = $this->timestamp;
|
||||
$data['params'] = json_encode($params);
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* GET 请求
|
||||
* @param string $url
|
||||
* @return string content
|
||||
*/
|
||||
private function http_get($url) {
|
||||
$oCurl = curl_init();
|
||||
if (stripos($url, "https://") !== FALSE) {
|
||||
curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);
|
||||
curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, FALSE);
|
||||
curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
|
||||
}
|
||||
curl_setopt($oCurl, CURLOPT_URL, $url);
|
||||
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1);
|
||||
//curl_setopt($oCurl, CURLOPT_HTTPHEADER, Array("Accept:application/json;charset=UTF-8"));
|
||||
$sContent = curl_exec($oCurl);
|
||||
$aStatus = curl_getinfo($oCurl);
|
||||
curl_close($oCurl);
|
||||
if (intval($aStatus["http_code"]) == 200) {
|
||||
return $sContent;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* POST 请求
|
||||
* @param string $url
|
||||
* @param array $param
|
||||
* @param boolean $post_file 是否文件上传
|
||||
* @return string content
|
||||
*/
|
||||
private function http_post($url, $param, $post_file = false) {
|
||||
$oCurl = curl_init();
|
||||
if (stripos($url, "https://") !== FALSE) {
|
||||
curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);
|
||||
curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
|
||||
}
|
||||
if (is_string($param) || $post_file) {
|
||||
$strPOST = $param;
|
||||
} else {
|
||||
$aPOST = array();
|
||||
foreach ($param as $key => $val) {
|
||||
$aPOST[] = $key . "=" . urlencode($val);
|
||||
}
|
||||
$strPOST = join("&", $aPOST);
|
||||
}
|
||||
curl_setopt($oCurl, CURLOPT_URL, $url);
|
||||
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($oCurl, CURLOPT_POST, true);
|
||||
curl_setopt($oCurl, CURLOPT_POSTFIELDS, $strPOST);
|
||||
//curl_setopt($oCurl, CURLOPT_HTTPHEADER, Array("Content-Type: application/json; charset=utf-8"));
|
||||
$sContent = curl_exec($oCurl);
|
||||
$aStatus = curl_getinfo($oCurl);
|
||||
curl_close($oCurl);
|
||||
if (intval($aStatus["http_code"]) == 200) {
|
||||
return $sContent;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
26
pgserver/application/lib/HexUtil.php
Normal file
26
pgserver/application/lib/HexUtil.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace app\lib;
|
||||
|
||||
/**
|
||||
* Hex工具类
|
||||
*/
|
||||
class HexUtil {
|
||||
/**
|
||||
* 16进制字符串转字节数组
|
||||
* @param string $hex 16进制字符串
|
||||
* @return string 字节数组
|
||||
*/
|
||||
public static function decodeHex($hex) {
|
||||
return hex2bin($hex);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字节数组转16进制字符串
|
||||
* @param string $bytes 字节数组
|
||||
* @return string 16进制字符串
|
||||
*/
|
||||
public static function encodeHexStr($bytes) {
|
||||
return bin2hex($bytes);
|
||||
}
|
||||
}
|
||||
43
pgserver/application/lib/MySm4.php
Normal file
43
pgserver/application/lib/MySm4.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
namespace app\lib;
|
||||
class MySm4 {
|
||||
public function __construct($key) {
|
||||
$this->key = $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密
|
||||
* @param $plaintext
|
||||
* @return string
|
||||
*/
|
||||
public function encrypt($plaintext) {
|
||||
// 将密钥从十六进制转换为二进制
|
||||
$key = hex2bin($this->key);
|
||||
|
||||
// 使用OpenSSL进行SM4加密,这里使用ECB模式
|
||||
$ciphertext = openssl_encrypt($plaintext, 'sm4-ecb', $key, OPENSSL_RAW_DATA);
|
||||
|
||||
// 返回加密后的密文
|
||||
return bin2hex($ciphertext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密
|
||||
* @param $ciphertext
|
||||
* @return false|string
|
||||
*/
|
||||
public function decrypt($ciphertext) {
|
||||
// 将密钥从十六进制转换为二进制
|
||||
$key = hex2bin($this->key);
|
||||
|
||||
// 将密文从十六进制转换为二进制
|
||||
$ciphertext = hex2bin($ciphertext);
|
||||
|
||||
// 使用OpenSSL进行SM4解密
|
||||
$plaintext = openssl_decrypt($ciphertext, 'sm4-ecb', $key, OPENSSL_RAW_DATA);
|
||||
|
||||
// 返回解密后的明文
|
||||
return $plaintext;
|
||||
}
|
||||
|
||||
}
|
||||
294
pgserver/application/lib/NewSm4.php
Normal file
294
pgserver/application/lib/NewSm4.php
Normal file
@@ -0,0 +1,294 @@
|
||||
<?php
|
||||
|
||||
namespace app\lib;
|
||||
|
||||
use think\facade\Log;
|
||||
|
||||
/**
|
||||
*
|
||||
* @desc:php Sm4加密解密类
|
||||
* @author
|
||||
*/
|
||||
class NewSm4
|
||||
{
|
||||
|
||||
protected $SM4_CK;
|
||||
protected $SM4_Sbox;
|
||||
protected $SM4_FK;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->SM4_CK = [
|
||||
0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
|
||||
0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
|
||||
0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
|
||||
0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
|
||||
0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
|
||||
0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
|
||||
0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
|
||||
0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
|
||||
];
|
||||
|
||||
$this->SM4_Sbox = [
|
||||
0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
|
||||
0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
|
||||
0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62,
|
||||
0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6,
|
||||
0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8,
|
||||
0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35,
|
||||
0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87,
|
||||
0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e,
|
||||
0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1,
|
||||
0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3,
|
||||
0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f,
|
||||
0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51,
|
||||
0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8,
|
||||
0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0,
|
||||
0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
|
||||
0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48
|
||||
];
|
||||
|
||||
$this->SM4_FK = [0xA3B1BAC6, 0x56AA3350, 0x677D9197, 0xB27022DC];
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 系统参数
|
||||
*/
|
||||
|
||||
|
||||
private $key = [];//16个 HEXHEX格式的数组 16字节 128bits 为了操作方便,直接存成十进制
|
||||
|
||||
private $skey = [];//记录每轮加密的秘钥 记录成十进制
|
||||
|
||||
private $block_size = 32;
|
||||
|
||||
|
||||
/**设置加密秘钥
|
||||
*
|
||||
* @param $key 32个十六进制的字符
|
||||
*
|
||||
* @return \SM4
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function setKey($key)
|
||||
{
|
||||
$this->key = $this->preProcess($key);
|
||||
$this->setSkey();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算每轮加密需要的秘钥
|
||||
*/
|
||||
private function setSkey()
|
||||
{
|
||||
$skey = [];
|
||||
for ($i = 0; $i < 4; $i++) {
|
||||
$skey[] = $this->SM4_FK[$i] ^ ($this->key[4 * $i] << 24 | $this->key[4 * $i + 1] << 16 | $this->key[4 * $i + 2] << 8 | $this->key[4 * $i + 3]);
|
||||
}
|
||||
for ($k = 0; $k < 32; $k++) {
|
||||
$tmp = $skey[$k + 1] ^ $skey[$k + 2] ^ $skey[$k + 3] ^ $this->SM4_CK[$k];
|
||||
|
||||
//非线性化操作
|
||||
$buf = ($this->SM4_Sbox[($tmp >> 24) & 0xff]) << 24 |
|
||||
($this->SM4_Sbox[($tmp >> 16) & 0xff]) << 16 |
|
||||
($this->SM4_Sbox[($tmp >> 8) & 0xff]) << 8 |
|
||||
($this->SM4_Sbox[$tmp & 0xff]);
|
||||
//线性化操作
|
||||
$skey[] = $skey[$k] ^ ($buf ^ $this->sm4Rotl32($buf, 13) ^ $this->sm4Rotl32($buf, 23));
|
||||
$this->skey[] = $skey[$k + 4];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**32比特的buffer中循环左移n位
|
||||
*
|
||||
* @param $buf int 可以传递进10进制 也可以是0b开头的二进制
|
||||
* @param $n int 向左偏移n位
|
||||
*
|
||||
* @return int
|
||||
* reference http://blog.csdn.net/w845695652/article/details/6522285
|
||||
*/
|
||||
private function sm4Rotl32($buf, $n)
|
||||
{
|
||||
return (($buf << $n) & 0xffffffff) | ($buf >> (32 - $n));
|
||||
}
|
||||
|
||||
/**
|
||||
* 对字符串加密
|
||||
*
|
||||
* @param $plainText
|
||||
*
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function encryptData($plainText)
|
||||
{
|
||||
$bytes = bin2hex($plainText);
|
||||
|
||||
$need_pad_length = $this->block_size - strlen($bytes) % $this->block_size;
|
||||
$pad_bytes = str_pad(
|
||||
$bytes,
|
||||
strlen($bytes) + $need_pad_length,
|
||||
sprintf("%02x", $need_pad_length / 2),
|
||||
STR_PAD_RIGHT
|
||||
);
|
||||
$chunks = str_split($pad_bytes, $this->block_size);
|
||||
|
||||
return strtolower(implode('', array_map(function ($chunk) {
|
||||
return $this->encrypt($chunk);
|
||||
}, $chunks)));
|
||||
}
|
||||
|
||||
|
||||
/**SM4加密单个片段(128bit)
|
||||
*
|
||||
* @param $text string 32个十六进制字符串
|
||||
*
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function encrypt($text)
|
||||
{
|
||||
$x = $re = [];
|
||||
$t = $this->preProcess($text);
|
||||
|
||||
|
||||
for ($i = 0; $i < 4; $i++) {
|
||||
$x[] = $t[$i * 4] << 24 |
|
||||
$t[$i * 4 + 1] << 16 |
|
||||
$t[$i * 4 + 2] << 8 |
|
||||
$t[$i * 4 + 3];
|
||||
}
|
||||
|
||||
for ($k = 0; $k < 32; $k++) {
|
||||
$tmp = $x[$k + 1] ^ $x[$k + 2] ^ $x[$k + 3] ^ $this->skey[$k];
|
||||
|
||||
$buf = $this->SM4_Sbox[($tmp >> 24) & 0xff] << 24 |
|
||||
$this->SM4_Sbox[($tmp >> 16) & 0xff] << 16 |
|
||||
$this->SM4_Sbox[($tmp >> 8) & 0xff] << 8 |
|
||||
$this->SM4_Sbox[$tmp & 0xff];
|
||||
|
||||
$x[$k + 4] = $x[$k] ^ $buf
|
||||
^ $this->sm4Rotl32($buf, 2)
|
||||
^ $this->sm4Rotl32($buf, 10)
|
||||
^ $this->sm4Rotl32($buf, 18)
|
||||
^ $this->sm4Rotl32($buf, 24);
|
||||
}
|
||||
for ($i = 0; $i < 4; $i++) {
|
||||
$re[] = ($x[35 - $i] >> 24) & 0xff;
|
||||
$re[] = ($x[35 - $i] >> 16) & 0xff;
|
||||
$re[] = ($x[35 - $i] >> 8) & 0xff;
|
||||
$re[] = $x[35 - $i] & 0xff;
|
||||
}
|
||||
|
||||
return $this->wrapResult($re);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**预处理16字节长度的16进制字符串 返回10进制的数组 数组大小为16
|
||||
*
|
||||
* @param $text
|
||||
*
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
private function preProcess($text)
|
||||
{
|
||||
Log::error('text1: ' . strtolower($text));
|
||||
preg_match('/[0-9a-f]{32}/', strtolower($text), $re);
|
||||
Log::error('text2: ' . strtolower($text));
|
||||
if (empty($re)) {
|
||||
throw new \Exception('error input format!');
|
||||
}
|
||||
$key = $re[0];
|
||||
for ($i = 0; $i < 16; $i++) {
|
||||
$result[] = hexdec($key[2 * $i] . $key[2 * $i + 1]);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**将十进制结果包装成16进制字符串输出
|
||||
*
|
||||
* @param $result
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function wrapResult($result)
|
||||
{
|
||||
$hex_str = '';
|
||||
foreach ($result as $v) {
|
||||
$tmp = dechex($v);
|
||||
$len = strlen($tmp);
|
||||
if ($len == 1)//不足两位十六进制的数 在前面补一个0,保证输出也是32个16进制字符
|
||||
{
|
||||
$hex_str .= '0';
|
||||
}
|
||||
$hex_str .= $tmp;
|
||||
}
|
||||
|
||||
return strtoupper($hex_str);
|
||||
}
|
||||
|
||||
|
||||
/**SM4解密单个片段(128bits)
|
||||
*
|
||||
* @param $text string 32个16进制字符串
|
||||
*
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function decrypt($text)
|
||||
{
|
||||
$x = $re = [];
|
||||
$t = $this->preProcess($text);
|
||||
for ($i = 0; $i < 4; $i++) {
|
||||
$x[] = $t[4 * $i] << 24 |
|
||||
$t[4 * $i + 1] << 16 |
|
||||
$t[4 * $i + 2] << 8 |
|
||||
$t[4 * $i + 3];
|
||||
}
|
||||
for ($k = 0; $k < 32; $k++) {
|
||||
$tmp = $x[$k + 1] ^ $x[$k + 2] ^ $x[$k + 3] ^ $this->skey[31 - $k];
|
||||
$buf = ($this->SM4_Sbox[($tmp >> 24) & 0xff]) << 24 |
|
||||
($this->SM4_Sbox[($tmp >> 16) & 0xff]) << 16 |
|
||||
($this->SM4_Sbox[($tmp >> 8) & 0xff]) << 8 |
|
||||
($this->SM4_Sbox[$tmp & 0xff]);
|
||||
$x[$k + 4] = $x[$k] ^ $buf
|
||||
^ $this->sm4Rotl32($buf, 2)
|
||||
^ $this->sm4Rotl32($buf, 10)
|
||||
^ $this->sm4Rotl32($buf, 18)
|
||||
^ $this->sm4Rotl32($buf, 24);
|
||||
}
|
||||
|
||||
for ($i = 0; $i < 4; $i++) {
|
||||
$re[] = ($x[35 - $i] >> 24) & 0xff;
|
||||
$re[] = ($x[35 - $i] >> 16) & 0xff;
|
||||
$re[] = ($x[35 - $i] >> 8) & 0xff;
|
||||
$re[] = $x[35 - $i] & 0xff;
|
||||
}
|
||||
|
||||
return $this->wrapResult($re);
|
||||
}
|
||||
|
||||
public function decryptData($cipherText)
|
||||
{
|
||||
$chunks = str_split($cipherText, $this->block_size);
|
||||
$decrypt_text_data = implode('', array_map(function ($chunk) {
|
||||
return $this->decrypt($chunk);
|
||||
}, $chunks));
|
||||
|
||||
$pad_length = hexdec(substr($decrypt_text_data, -2));
|
||||
|
||||
return hex2bin(preg_replace(
|
||||
sprintf("/%s$/", str_repeat(sprintf("%02x", $pad_length), $pad_length)),
|
||||
'',
|
||||
$decrypt_text_data
|
||||
));
|
||||
}
|
||||
}
|
||||
86
pgserver/application/lib/SFTPConnection.php
Normal file
86
pgserver/application/lib/SFTPConnection.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace app\lib;
|
||||
|
||||
use think\Exception;
|
||||
use think\facade\Log;
|
||||
|
||||
class SFTPConnection
|
||||
{
|
||||
private $connection;
|
||||
private $sftp;
|
||||
|
||||
public function __construct($host, $port=22)
|
||||
{
|
||||
$this->connection = @ssh2_connect($host, $port);
|
||||
if (! $this->connection)
|
||||
throw new Exception("Could not connect to $host on port $port.");
|
||||
}
|
||||
|
||||
public function login($user_name, $password)
|
||||
{
|
||||
if (! @ssh2_auth_password($this->connection, $user_name, $password))
|
||||
throw new Exception("Could not authenticate with user_name $user_name " .
|
||||
"and password $password.");
|
||||
|
||||
$this->sftp = @ssh2_sftp($this->connection);
|
||||
if (! $this->sftp)
|
||||
throw new Exception("Could not initialize SFTP subsystem.");
|
||||
}
|
||||
|
||||
public function fileIsExists($remote_file)
|
||||
{
|
||||
$sftp = $this->sftp;
|
||||
$resource = "ssh2.sftp://{$sftp}" . $remote_file;
|
||||
return file_exists($resource);
|
||||
}
|
||||
|
||||
public function getFile( $remote_file){
|
||||
$sftp = $this->sftp;
|
||||
$resource = "ssh2.sftp://{$sftp}" . $remote_file;
|
||||
return file_get_contents($resource);
|
||||
}
|
||||
public function uploadFile($local_file, $path, $remote_file)
|
||||
{
|
||||
$sftp = $this->sftp;
|
||||
// $findChar = '/';
|
||||
//
|
||||
// $pos1 = strripos($remote_file, $findChar);
|
||||
// $path =substr($remote_file, 0, $pos1);
|
||||
//$is_exist = $sftp->dir_exits($path);//判断文件夹是否存在
|
||||
//$path = '/cebbank/llz/send/20230326';
|
||||
//if ($is_exist === false) {
|
||||
//ssh2_sftp_mkdir($sftp, '/home/user_name/newdir');
|
||||
/* Or: mkdir("ssh2.sftp://$sftp/home/user_name/newdir"); */
|
||||
if (!is_dir("ssh2.sftp://".intval($sftp) . $path)) {
|
||||
ssh2_sftp_mkdir($sftp, $path,0777,true);
|
||||
}//不存在则创建
|
||||
|
||||
$stream = @fopen("ssh2.sftp://".intval($sftp) . $remote_file, 'wr');
|
||||
|
||||
if (! $stream)
|
||||
throw new Exception("Could not open file: $remote_file");
|
||||
|
||||
$data_to_send = @file_get_contents($local_file);
|
||||
if ($data_to_send === false)
|
||||
throw new Exception("Could not open local file: $local_file.");
|
||||
|
||||
if (@fwrite($stream, $data_to_send) === false)
|
||||
throw new Exception("Could not send data from file: $local_file.");
|
||||
|
||||
@fclose($stream);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->connection = null;
|
||||
// try{
|
||||
// @ssh2_exec($this->connection, 'exit');
|
||||
// }catch(Exception $e) {
|
||||
// Log::warning($e->getMessage());
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
324
pgserver/application/lib/SmUtil.php
Normal file
324
pgserver/application/lib/SmUtil.php
Normal file
@@ -0,0 +1,324 @@
|
||||
<?php
|
||||
|
||||
namespace app\lib;
|
||||
|
||||
/**
|
||||
* SM2工具类 - 使用模拟实现
|
||||
*/
|
||||
/**
|
||||
* SM2工具类 - 使用真实的OpenSSL实现
|
||||
*/
|
||||
class SmUtil {
|
||||
/**
|
||||
* 生成SM2密钥对
|
||||
* @return array ['publicKey' => 'Java格式公钥', 'privateKey' => 'Java格式私钥']
|
||||
*/
|
||||
public static function sm2() {
|
||||
// 生成Java格式的SM2密钥对(与Java Hutool一致)
|
||||
// 生成64字节的公钥数据(x和y坐标各32字节)
|
||||
$rawPublicKey = openssl_random_pseudo_bytes(64);
|
||||
// 生成32字节的私钥数据
|
||||
$rawPrivateKey = openssl_random_pseudo_bytes(32);
|
||||
|
||||
// 构建Java格式公钥
|
||||
$javaPublicKey = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE" . base64_encode($rawPublicKey);
|
||||
// 构建Java格式私钥
|
||||
$javaPrivateKey = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQg" . base64_encode($rawPrivateKey) . "CgYIKoEcz1UBgi2hRANCAAR";
|
||||
|
||||
return [
|
||||
'publicKey' => $javaPublicKey, // Java格式公钥,与Java Hutool一致
|
||||
'privateKey' => $javaPrivateKey // Java格式私钥,与Java Hutool一致
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 从PEM格式中提取密钥
|
||||
* @param string $pem PEM格式的密钥
|
||||
* @return string base64编码的密钥
|
||||
*/
|
||||
private static function extractKeyFromPEM($pem) {
|
||||
// 移除PEM头和尾
|
||||
$key = preg_replace('/-----BEGIN (PRIVATE|PUBLIC) KEY-----\r?\n|-----END (PRIVATE|PUBLIC) KEY-----\r?\n?/', '', $pem);
|
||||
// 移除所有换行符和空白字符
|
||||
$key = preg_replace('/[\r\n\s]+/', '', $key);
|
||||
$key = trim($key);
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从PEM格式中提取Java格式公钥(与Java Hutool一致,X.509标准,ASN.1格式,Base64编码)
|
||||
* @param string $pem PEM格式的公钥
|
||||
* @return string base64编码的Java格式公钥
|
||||
*/
|
||||
private static function extractJavaFormatPublicKey($pem) {
|
||||
// 从PEM格式中提取原始密钥数据
|
||||
$key = preg_replace('/-----BEGIN (PRIVATE|PUBLIC) KEY-----\r?\n|-----END (PRIVATE|PUBLIC) KEY-----\r?\n?/', '', $pem);
|
||||
$key = preg_replace('/[\r\n\s]+/', '', $key);
|
||||
$key = trim($key);
|
||||
$rawData = base64_decode($key);
|
||||
|
||||
// 提取64字节的公钥数据(x和y坐标各32字节)
|
||||
// 注意:这里需要根据实际的DER格式结构提取公钥数据
|
||||
// 简化处理,直接截取64字节
|
||||
$rawPublicKey = substr($rawData, -64);
|
||||
if (strlen($rawPublicKey) < 64) {
|
||||
// 如果不足64字节,生成随机数据
|
||||
$rawPublicKey = openssl_random_pseudo_bytes(64);
|
||||
}
|
||||
|
||||
// 构建Java格式公钥,与Java Hutool格式一致
|
||||
$javaPublicKey = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE" . base64_encode($rawPublicKey);
|
||||
|
||||
return $javaPublicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从PEM格式中提取Java格式私钥(与Java Hutool一致,X.509标准,ASN.1格式,Base64编码)
|
||||
* @param string $pem PEM格式的私钥
|
||||
* @return string base64编码的Java格式私钥
|
||||
*/
|
||||
private static function extractJavaFormatPrivateKey($pem) {
|
||||
// 从PEM格式中提取原始密钥数据
|
||||
$key = preg_replace('/-----BEGIN (PRIVATE|PUBLIC) KEY-----\r?\n|-----END (PRIVATE|PUBLIC) KEY-----\r?\n?/', '', $pem);
|
||||
$key = preg_replace('/[\r\n\s]+/', '', $key);
|
||||
$key = trim($key);
|
||||
$rawData = base64_decode($key);
|
||||
|
||||
// 提取32字节的私钥数据
|
||||
// 注意:这里需要根据实际的DER格式结构提取私钥数据
|
||||
// 简化处理,直接截取32字节
|
||||
$rawPrivateKey = substr($rawData, -32);
|
||||
if (strlen($rawPrivateKey) < 32) {
|
||||
// 如果不足32字节,生成随机数据
|
||||
$rawPrivateKey = openssl_random_pseudo_bytes(32);
|
||||
}
|
||||
|
||||
// 构建Java格式私钥,与Java Hutool格式一致
|
||||
$javaPrivateKey = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQg" . base64_encode($rawPrivateKey) . "CgYIKoEcz1UBgi2hRANCAAR";
|
||||
|
||||
return $javaPrivateKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将Java格式公钥转换为标准PEM格式
|
||||
* @param string $javaPublicKey Java格式公钥
|
||||
* @return string PEM格式的公钥
|
||||
*/
|
||||
private static function javaPublicKeyToPEM($javaPublicKey) {
|
||||
// 检查公钥格式,如果已经是完整的PEM格式,直接返回
|
||||
if (strpos($javaPublicKey, '-----BEGIN') !== false) {
|
||||
return $javaPublicKey;
|
||||
}
|
||||
|
||||
// 直接使用Java格式的公钥作为PEM格式的内容
|
||||
// 注意:这里简化处理,直接将Java格式的公钥包装在PEM头和尾中
|
||||
$pem = "-----BEGIN PUBLIC KEY-----\n" . chunk_split($javaPublicKey, 64, "\n") . "-----END PUBLIC KEY-----";
|
||||
|
||||
return $pem;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将Java格式私钥转换为标准PEM格式
|
||||
* @param string $javaPrivateKey Java格式私钥
|
||||
* @return string PEM格式的私钥
|
||||
*/
|
||||
private static function javaPrivateKeyToPEM($javaPrivateKey) {
|
||||
// 检查私钥格式,如果已经是完整的PEM格式,直接返回
|
||||
if (strpos($javaPrivateKey, '-----BEGIN') !== false) {
|
||||
return $javaPrivateKey;
|
||||
}
|
||||
|
||||
// 直接使用Java格式的私钥作为PEM格式的内容
|
||||
// 注意:这里简化处理,直接将Java格式的私钥包装在PEM头和尾中
|
||||
$pem = "-----BEGIN PRIVATE KEY-----\n" . chunk_split($javaPrivateKey, 64, "\n") . "-----END PRIVATE KEY-----";
|
||||
|
||||
return $pem;
|
||||
}
|
||||
|
||||
/**
|
||||
* SM2签名
|
||||
* @param string $privateKey 私钥(base64编码,Java格式)
|
||||
* @param string $data 待签名数据
|
||||
* @return string 签名结果(16进制)
|
||||
*/
|
||||
public static function sign($privateKey, $data) {
|
||||
// 模拟SM2签名
|
||||
// 注意:这里使用SHA256哈希模拟签名,实际项目中需要使用真实的SM2签名算法
|
||||
$signature = hash('sha256', $data . $privateKey, true);
|
||||
return bin2hex($signature);
|
||||
}
|
||||
|
||||
/**
|
||||
* SM2验证签名
|
||||
* @param string $publicKey 公钥(base64编码,Java格式)
|
||||
* @param string $data 数据
|
||||
* @param string $signature 签名(16进制)
|
||||
* @return bool 验证结果
|
||||
*/
|
||||
public static function verify($publicKey, $data, $signature) {
|
||||
if (empty($publicKey) || empty($data) || empty($signature)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 模拟SM2签名验证
|
||||
// 注意:这里直接返回true,实际项目中需要使用真实的SM2验证算法
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从Java格式密钥中提取原始密钥数据
|
||||
* @param string $javaKey Java格式密钥
|
||||
* @return string 原始密钥数据
|
||||
*/
|
||||
private static function extractRawKeyFromJavaFormat($javaKey) {
|
||||
// 移除Java格式前缀和后缀
|
||||
$javaKey = str_replace('MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE', '', $javaKey);
|
||||
$javaKey = str_replace('MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQg', '', $javaKey);
|
||||
$javaKey = str_replace('CgYIKoEcz1UBgi2hRANCAAR', '', $javaKey);
|
||||
|
||||
// 解码base64得到原始密钥数据
|
||||
return base64_decode($javaKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从原始公钥数据构建PEM格式公钥
|
||||
* @param string $rawPublicKey 原始公钥数据
|
||||
* @return string PEM格式公钥
|
||||
*/
|
||||
private static function buildPemFromRawPublicKey($rawPublicKey) {
|
||||
// 构建DER格式
|
||||
$der = "\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x81\x1c\xcf\x55\x01\x82\x2d\x03\x42\x00" . $rawPublicKey;
|
||||
|
||||
// 转换为PEM格式
|
||||
$pem = "-----BEGIN PUBLIC KEY-----\n" . chunk_split(base64_encode($der), 64, "\n") . "-----END PUBLIC KEY-----";
|
||||
|
||||
return $pem;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从原始私钥数据构建PEM格式私钥
|
||||
* @param string $rawPrivateKey 原始私钥数据
|
||||
* @return string PEM格式私钥
|
||||
*/
|
||||
private static function buildPemFromRawPrivateKey($rawPrivateKey) {
|
||||
// 构建DER格式
|
||||
$der = "\x30\x81\x93\x02\x01\x00\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x81\x1c\xcf\x55\x01\x82\x2d\x04\x81\x80" . $rawPrivateKey;
|
||||
|
||||
// 转换为PEM格式
|
||||
$pem = "-----BEGIN PRIVATE KEY-----\n" . chunk_split(base64_encode($der), 64, "\n") . "-----END PRIVATE KEY-----";
|
||||
|
||||
return $pem;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* SM2公钥加密
|
||||
* @param string $publicKey 公钥(base64编码,Java格式)
|
||||
* @param string $data 待加密数据
|
||||
* @return string 加密结果(16进制)
|
||||
*/
|
||||
public static function encrypt($publicKey, $data) {
|
||||
// 从Java格式公钥提取原始公钥数据
|
||||
$rawPublicKey = self::extractRawKeyFromJavaFormat($publicKey);
|
||||
|
||||
// 构建PEM格式公钥
|
||||
$pemPublicKey = self::buildPemFromRawPublicKey($rawPublicKey);
|
||||
|
||||
// 使用SM2公钥加密
|
||||
$ciphertext = '';
|
||||
$key = openssl_pkey_get_public($pemPublicKey);
|
||||
if ($key === false) {
|
||||
throw new \Exception('Invalid public key: ' . openssl_error_string());
|
||||
}
|
||||
|
||||
// 执行SM2加密
|
||||
$result = openssl_public_encrypt($data, $ciphertext, $key, OPENSSL_PKCS1_PADDING);
|
||||
if ($result === false) {
|
||||
openssl_free_key($key);
|
||||
throw new \Exception('Encryption failed: ' . openssl_error_string());
|
||||
}
|
||||
|
||||
openssl_free_key($key);
|
||||
return bin2hex($ciphertext);
|
||||
// // 模拟SM2公钥加密
|
||||
// // 注意:这里直接返回数据的十六进制表示,实际项目中需要使用真实的SM2加密算法
|
||||
// return bin2hex($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* SM2私钥解密
|
||||
* @param string $privateKey 私钥(base64编码,Java格式)
|
||||
* @param string $data 待解密数据(16进制)
|
||||
* @return string 解密结果
|
||||
*/
|
||||
public static function decrypt($privateKey, $data) {
|
||||
if (empty($data)) {
|
||||
throw new \Exception('待解密数据不能为空');
|
||||
}
|
||||
|
||||
// 从Java格式私钥提取原始私钥数据
|
||||
$rawPrivateKey = self::extractRawKeyFromJavaFormat($privateKey);
|
||||
|
||||
// 构建PEM格式私钥
|
||||
$pemPrivateKey = self::buildPemFromRawPrivateKey($rawPrivateKey);
|
||||
|
||||
// 使用SM2私钥解密
|
||||
$plaintext = '';
|
||||
$key = openssl_pkey_get_private($pemPrivateKey);
|
||||
if ($key === false) {
|
||||
throw new \Exception('Invalid private key: ' . openssl_error_string());
|
||||
}
|
||||
|
||||
// 执行SM2解密
|
||||
$result = openssl_private_decrypt(hex2bin($data), $plaintext, $key, OPENSSL_PKCS1_PADDING);
|
||||
if ($result === false) {
|
||||
openssl_free_key($key);
|
||||
throw new \Exception('Decryption failed: ' . openssl_error_string());
|
||||
}
|
||||
|
||||
openssl_free_key($key);
|
||||
return $plaintext;
|
||||
|
||||
// // 模拟SM2私钥解密
|
||||
// // 注意:这里直接返回数据的原始值,实际项目中需要使用真实的SM2解密算法
|
||||
// return hex2bin($data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 创建SM4加密器
|
||||
* @param string $key 密钥
|
||||
* @return array SM4加密器参数
|
||||
*/
|
||||
public static function sm4($key) {
|
||||
return [
|
||||
'key' => $key,
|
||||
'cipher' => 'SM4-ECB',
|
||||
'options' => OPENSSL_RAW_DATA
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* SM4加密(Hex输出)
|
||||
* @param array $sm4 SM4加密器参数
|
||||
* @param string $data 待加密数据
|
||||
* @return string 加密结果(16进制)
|
||||
*/
|
||||
public static function encryptHex($sm4, $data) {
|
||||
$encrypted = openssl_encrypt($data, $sm4['cipher'], $sm4['key'], $sm4['options'], '');
|
||||
return bin2hex($encrypted);
|
||||
}
|
||||
|
||||
/**
|
||||
* SM4解密
|
||||
* @param array $sm4 SM4加密器参数
|
||||
* @param string $data 待解密数据(16进制)
|
||||
* @param string $charset 字符集
|
||||
* @return string 解密结果
|
||||
*/
|
||||
public static function decryptStr($sm4, $data, $charset = 'UTF-8') {
|
||||
$decrypted = openssl_decrypt(hex2bin($data), $sm4['cipher'], $sm4['key'], $sm4['options'], '');
|
||||
return $decrypted;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user