config = $config; } /** * 数据校验 * @param array $data 待校验数据 * @return bool */ private function checkData(array $data) { // 非空校验 if( count($data) == 0 ) { $this->err_msg = '待签名数据为空'; return false; } // 一维数组校验 if( count($data) != count($data, 1) ) { $this->err_msg = '待签名数据不能是多维数组'; return false; } return true; } /** * 生成签名 * @param array $data 待签名数据 * @return bool|string */ public function makeSign(array $data) { // 数据校验 $check_data = $this->checkData($data); if($check_data === false) { return false; } // 升序排列 ksort($data); // 转字符串 $pre_sign_str = http_build_query($data); // echo "[pre_sign_str(jiao yi message)]: {$pre_sign_str}"; // die(); // 读取私钥 $private_key = file_get_contents($this->config['private_key']); $private_key = openssl_pkey_get_private($private_key); // 私钥签名 $res = openssl_sign($pre_sign_str, $sign, $private_key); if($res === false) { $this->err_msg = openssl_error_string(); return false; } // 签名转Base64 $sign = base64_encode($sign); return $sign; } /** * 校验签名 * @param array $data 待校验数据 * @param string $sign 签名 * @return bool */ public function checkSign(array $data, string $sign) { // 数据校验 $check_data = $this->checkData($data); if($check_data === false) { return false; } // 签名转二进制 $sign = base64_decode($sign); // 升序排列 ksort($data); // 转字符串 $pre_sign_str = http_build_query($data); $pre_sign_str = urldecode($pre_sign_str); // echo "[pre sign str]: {$pre_sign_str}"; // die(); // 读取公钥 $public_key = file_get_contents($this->config['public_key']); $public_key = openssl_pkey_get_public($public_key); // 公钥验签 $res = openssl_verify($pre_sign_str, $sign, $public_key); if($res === false) { $this->err_msg = openssl_error_string(); return false; } return $res; } /** * 加密交易报文 * @param array $data 待签名数据 * @return bool|string */ public function encryptTradeData(array $data) { // 数据校验 $check_data = $this->checkData($data); if($check_data === false) { return false; } // 读取公钥 $public_key = file_get_contents($this->config['public_key']); $public_key = openssl_pkey_get_public($public_key); // 公钥长度(bit) $public_key_info = openssl_pkey_get_details($public_key); $public_key_bit = $public_key_info['bits']; // 数据长度(数据长度=密钥字节数-11,11为OPENSSL_PKCS1_PADDING的填充长度) $data_length = $public_key_bit / 8 - 11; // 待加密数据转json $pre_encrypt_data = json_encode($data, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES); // 按密钥长度拆分数据 $pre_encrypt_data_arr = str_split($pre_encrypt_data, $data_length); // 分段公钥加密 $crypted_data = ''; foreach($pre_encrypt_data_arr as $key=>$val) { $res = openssl_public_encrypt($val, $crypted_data_tmp, $public_key, OPENSSL_PKCS1_PADDING); if($res === false) { $this->err_msg = openssl_error_string(); return false; } $crypted_data .= $crypted_data_tmp; } // 加密结果转Base64 $crypted_data = base64_encode($crypted_data); return $crypted_data; } /** * 解密交易报文 * @param string $data 加密的交易报文 * @return bool|array */ public function decryptTradeData($data) { // 加密数据转二进制 $pre_decrypt_data = base64_decode($data); // $pre_decrypt_data = mb_convert_encoding($pre_decrypt_data, 'UTF-8', 'GBK'); // sc_test // echo "pre_decrypt_data\r\n"; // echo $pre_decrypt_data . "\r\n"; // 读取私钥 $private_key = file_get_contents($this->config['private_key']); $private_key = openssl_pkey_get_private($private_key); // 私钥长度(bit) $private_key_info = openssl_pkey_get_details($private_key); $private_key_bit = $private_key_info['bits']; // 数据长度(数据长度=密钥字节数,解密时无需考虑OPENSSL_PKCS1_PADDING的填充占位) $data_length = $private_key_bit / 8; // 按密钥长度拆分数据 $pre_decrypt_data_arr = str_split($pre_decrypt_data, $data_length); // 分段私钥解密 $decrypted_data = ''; foreach($pre_decrypt_data_arr as $key=>$val) { $res = openssl_private_decrypt($val, $decrypted_data_tmp, $private_key, OPENSSL_PKCS1_PADDING); echo "res:\r\n"; echo $res . "\r\n"; if($res === false) { $this->err_msg = openssl_error_string(); return false; } $decrypted_data .= $decrypted_data_tmp; } // echo "after decrypted.\r\n"; // $decrypted_data = mb_convert_encoding($decrypted_data, 'UTF-8', 'GBK'); // echo $decrypted_data . "\r\n"; // 解密结果编码转换(JAVA处理后的中文一般为GBK编码) // echo "\r\n"; // var_dump($decrypted_data); $charset = mb_detect_encoding($decrypted_data); // 这个东西有点问题 解析出来是false 先不用了 echo "\r\n"; var_dump($charset); echo "\r\n"; $decrypted_data = mb_convert_encoding($decrypted_data, 'UTF-8', 'GBK'); // echo "\r\n"; // var_dump($decrypted_data); return $decrypted_data; } } ?>