first commit

This commit is contained in:
annnj-company
2026-04-17 18:29:53 +08:00
parent e49fa5a215
commit 130c1026c4
5615 changed files with 1639145 additions and 0 deletions

View 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。UrlBase64AEStojson返回结果
* @param sign MD5SALT+ciphertext
* @param cipherkey 用RSA公钥对AES的秘钥进行加密转base64。UrlBase64RSAAES秘钥
* @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。UrlBase64AEStojson返回结果
* @param sign MD5SALT+ciphertext
* @param cipherkey 用RSA公钥对AES的秘钥进行加密转base64。UrlBase64RSAAES秘钥
* @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。UrlBase64AEStojson返回结果
* @param sign MD5SALT+ciphertext
* @param cipherkey 用RSA公钥对AES的秘钥进行加密转base64。UrlBase64RSAAES秘钥
* @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。UrlBase64AEStojson返回结果
* @param sign MD5SALT+ciphertext
* @param cipherkey 用RSA公钥对AES的秘钥进行加密转base64。UrlBase64RSAAES秘钥
* @param companyCode 评估公司编码
* @return string 查询结果json字符串
*/
public function officialResult($data){
}
}