372 lines
15 KiB
PHP
372 lines
15 KiB
PHP
<?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){
|
||
|
||
}
|
||
|
||
|
||
}
|