| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- <?php
- namespace common\helpers\UPOP;
- use common\helpers\LoggerTool;
- class PaySign {
- private $frontPayUrl;
- private $backPayUrl;
- private $agencyId;
- private $terminalId;
- private $childMerchantId;
- private $notifyUrl;
- private $returnUrl;
- public function __construct()
- {
- $this->frontPayUrl = \Yii::$app->params['UPOP']['frontPayUrl'];
- $this->backPayUrl = \Yii::$app->params['UPOP']['backPayUrl'];
- $this->agencyId = \Yii::$app->params['UPOP']['agencyId'];
- $this->terminalId = \Yii::$app->params['UPOP']['terminalId'];
- $this->childMerchantId = \Yii::$app->params['UPOP']['childMerchantId'];
- $this->notifyUrl = \Yii::$app->params['UPOP']['notifyUrl'];
- $this->returnUrl = \Yii::$app->params['UPOP']['returnUrl'];
- }
- public function sendEncodeData($payload, $url)
- {
- $json_content = json_encode($payload);
- // 随机生成aes密钥
- $aes_key = $this->randomKeys();
- // 商户RSA私钥
- $private_rsa_key = file_get_contents($this->getPath() . $this->agencyId . '/' . $this->agencyId. '.pem');
- // 平台RSA公钥
- $public_rsa_key = file_get_contents($this->getPath() . $this->agencyId . '/' . 'GHT_ROOT.pem');
- // 用随机生成的aes密钥加密请求报文
- $data['encryptData'] = $this->aesEncode($json_content, $aes_key);
- // 用我司平台rsa公钥加密上面随机生成的aes密钥
- $data['encryptKey'] = $this->rsaEncode($aes_key, $public_rsa_key);
- // 用商户ras私钥签名
- $data['signData'] = $this->rsaSign($json_content, $private_rsa_key);
- // 商户号
- $data['agencyId'] = $this->agencyId;
- $data_content = json_encode($data);
- LoggerTool::info($data_content);
- // 发送请求
- $request_result = $this->httpPost($data_content, $url);
- // 解密返回报文
- $result_json = json_decode($request_result,true);
- LoggerTool::info($result_json);
- // 用商户私钥解密aes密钥(是由平台随机生成的)
- $result_aes_key = $this->rsaDecode($result_json['encryptKey'], $private_rsa_key);
- // 用aes密钥解密报文
- $decode_content = $this->aesDecode($result_json['encryptData'], $result_aes_key);
- // 用平台公钥验签
- if ($this->verifySign($decode_content, $result_json['signData'], $public_rsa_key)) {
- return json_decode($decode_content, true);
- } else {
- // 验签失败
- return false;
- }
- }
- private function aesEncode($data, $aes_key): string
- {
- $encrypt_data = openssl_encrypt($this->pad($data), "aes-128-ecb", $aes_key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING);
- return base64_encode($encrypt_data);
- }
- public function aesDecode($data,$aes_key)
- {
- $data = base64_decode($data);
- return openssl_decrypt($data, "aes-128-ecb", $aes_key, OPENSSL_RAW_DATA);
- }
- private function rsaEncode($data, $public_rsa_key)
- {
- $ret = false;
- // if (!self::_checkPadding(OPENSSL_PKCS1_PADDING, 'en')){
- // return 'padding error';
- // }
- $key = openssl_get_publickey($public_rsa_key);
- if (openssl_public_encrypt($data,$result,$key,OPENSSL_PKCS1_PADDING)) {
- $ret = base64_encode($result);
- }
- return $ret;
- }
- private function rsaDecode($data, $private_rsa_key)
- {
- $ret = false;
- $data = base64_decode($data);
- if ($data !== false){
- if (openssl_private_decrypt($data, $result, $private_rsa_key, OPENSSL_PKCS1_PADDING)){
- $ret = $result;
- }
- }
- return $ret;
- }
- private function rsaSign($data, $private_rsa_key)
- {
- $res = openssl_get_privatekey($private_rsa_key);
- openssl_sign($data,$sign, $res);
- openssl_free_key($res);
- return base64_encode($sign);
- }
- private function verifySign($data, $signData, $public_rsa_key): bool
- {
- $signData =base64_decode($signData);
- $res = openssl_get_publickey($public_rsa_key);
- $result = openssl_verify($data, $signData, $res);
- openssl_free_key($res);
- if ($result === 1) {
- return true;
- } else {
- return false;
- }
- }
- private function httpPost($data, $url): string
- {
- try {
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/json'));
- curl_setopt($ch,CURLOPT_TIMEOUT,600);
- curl_setopt($ch,CURLOPT_URL, $url);
- curl_setopt($ch,CURLOPT_POST,true);
- curl_setopt($ch,CURLOPT_POSTFIELDS, $data);
- curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
- if (strpos($url, 'https') !== false) {
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
- curl_setopt($ch, CURLOPT_SSLVERSION, 1);
- }
- $ret_data = trim(curl_exec($ch));
- curl_close($ch);
- return $ret_data;
- } catch (\Exception $e) {
- LoggerTool::info($e->getMessage());
- return '';
- }
- }
- /*
- * 获取授权文件位置.
- */
- private function getPath()
- {
- return \Yii::getAlias('@common/runtime/upop/');
- // return dirname(__FILE__) . '/';
- }
- private function randomKeys(): string
- {
- $key = '';
- $pattern = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLOMNOPQRSTUVWXYZ';
- for ($i = 0; $i < 16; $i++) {
- $key .= $pattern[mt_rand(0, 35)];
- }
- return $key;
- }
- private function pad($data, $blocksize = 16): string
- {
- $pad = 16 - (strlen($data) % 16);
- return $data . str_repeat(chr($pad), $pad);
- }
- }
|