getConfig()->getAppid(); $body['mchid'] = $this->getConfig()->getMchId(); $body['description'] = $this->getConfig()->getBody(); $body['out_trade_no'] = $orderNo; $body['notify_url'] = $this->getConfig()->getNotifyUrl(); $body['amount'] = ['total' => $total, 'currency' => 'CNY']; return $body; } /** * @param string $http_method * @param string $canonical_url * @param string $body * @return string * @throws Exception */ public function signature(string $http_method, string $canonical_url, string $body = ''): string { $message = $http_method . "\n" . $canonical_url . "\n" . ($time = time()) . "\n" . ($rand = md5(random_bytes(32))) . "\n" . $body . "\n"; $sign = $this->openssl_signature($message); return sprintf('%s mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"', $this->getConfig()->getSchema(), $this->getConfig()->getMchId(), $rand, $time, $this->getConfig()->getSerialNo(), $sign); } /** * @param $body * @return string */ public function openssl_signature($body): string { $pem = file_get_contents($this->getConfig()->getSslCert()); $mch_private_key = openssl_get_privatekey($pem); openssl_sign($body, $raw_sign, $mch_private_key, 'sha256WithRSAEncryption'); return base64_encode($raw_sign); } /** * @param $json * @param $body * @return array */ private function createResponse($json, $body): array { $responseArray['appId'] = $body['appid']; $responseArray['timeStamp'] = (string)time(); $responseArray['nonceStr'] = Help::random(32); $responseArray['package'] = "prepay_id=" . $json['prepay_id']; $responseBody = $responseArray['appId'] . PHP_EOL . $responseArray['timeStamp'] . PHP_EOL . $responseArray['nonceStr'] . PHP_EOL . $responseArray['package'] . PHP_EOL; $responseArray['signType'] = 'RSA'; $responseArray['signBody'] = $responseBody; $responseArray['paySign'] = $this->openssl_signature($responseBody); $responseArray['prepay_id'] = $json['prepay_id']; return $responseArray; } /** * @param $associatedData * @param $nonceStr * @param $ciphertext * @return bool|string */ public function decryptToString($associatedData, $nonceStr, $ciphertext): bool|string { $ciphertext = \base64_decode($ciphertext); if (strlen($ciphertext) <= AUTH_TAG_LENGTH_BYTE) { return FALSE; } if (function_exists('\sodium\crypto_aead_aes256gcm_is_available') && crypto_aead_aes256gcm_is_available()) { return crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, 'XGwwZbmMXy6sD5w0IrxfaBHLl7b7jCaR'); } if (function_exists('\Sodium\crypto_aead_aes256gcm_is_available') && crypto_aead_aes256gcm_is_available()) { return crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, 'XGwwZbmMXy6sD5w0IrxfaBHLl7b7jCaR'); } if (PHP_VERSION_ID >= 70100 && in_array('aes-256-gcm', \openssl_get_cipher_methods())) { $ctext = substr($ciphertext, 0, -AUTH_TAG_LENGTH_BYTE); $authTag = substr($ciphertext, -AUTH_TAG_LENGTH_BYTE); return \openssl_decrypt($ctext, 'aes-256-gcm', 'XGwwZbmMXy6sD5w0IrxfaBHLl7b7jCaR', \OPENSSL_RAW_DATA, $nonceStr, $authTag, $associatedData); } throw new \RuntimeException('AEAD_AES_256_GCM需要PHP 7.1以上或者安装libsodium-php'); } }