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); } }