Default Changelist

This commit is contained in:
xl
2023-11-07 15:39:46 +08:00
parent a876b780f5
commit 459d298983
+86 -84
View File
@@ -7,108 +7,110 @@ use wchat\common\Help;
use function Sodium\crypto_aead_aes256gcm_decrypt; use function Sodium\crypto_aead_aes256gcm_decrypt;
use function Sodium\crypto_aead_aes256gcm_is_available; use function Sodium\crypto_aead_aes256gcm_is_available;
const KEY_LENGTH_BYTE = 32; const KEY_LENGTH_BYTE = 32;
const AUTH_TAG_LENGTH_BYTE = 16; const AUTH_TAG_LENGTH_BYTE = 16;
trait WxV3PaymentTait trait WxV3PaymentTait
{ {
/** /**
* @param $orderNo * @param $orderNo
* @param $total * @param $total
* @return array * @return array
*/ */
public function getInitCore($orderNo, $total): array public function getInitCore($orderNo, $total): array
{ {
$body['appid'] = $this->getConfig()->getAppid(); $body['appid'] = $this->getConfig()->getAppid();
$body['mchid'] = $this->getConfig()->getMchId(); $body['mchid'] = $this->getConfig()->getMchId();
$body['description'] = $this->getConfig()->getBody(); $body['description'] = $this->getConfig()->getBody();
$body['out_trade_no'] = $orderNo; $body['out_trade_no'] = $orderNo;
$body['notify_url'] = $this->getConfig()->getNotifyUrl(); $body['notify_url'] = $this->getConfig()->getNotifyUrl();
$body['amount'] = ['total' => $total, 'currency' => 'CNY']; $body['amount'] = ['total' => $total, 'currency' => 'CNY'];
return $body; return $body;
} }
/** /**
* @param string $http_method * @param string $http_method
* @param string $canonical_url * @param string $canonical_url
* @param string $body * @param string $body
* @return string * @return string
* @throws Exception * @throws Exception
*/ */
public function signature(string $http_method, string $canonical_url, string $body = ''): string 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"; $rand = md5(random_bytes(32));
$time = time();
$message = sprintf("%s\n%s\n%d\n%s\n\n", $http_method, $canonical_url, $time, $rand);
$sign = $this->openssl_signature($message); $sign = $this->openssl_signature($message);
return sprintf('%s mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"', $this->getConfig()->getSchema(), 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); $this->getConfig()->getMchId(), $rand, $time, $this->getConfig()->getSerialNo(), $sign);
} }
/** /**
* @param $body * @param $body
* @return string * @return string
*/ */
public function openssl_signature($body): string public function openssl_signature($body): string
{ {
$pem = file_get_contents($this->getConfig()->getSslCert()); $pem = file_get_contents($this->getConfig()->getSslCert());
$mch_private_key = openssl_get_privatekey($pem); $mch_private_key = openssl_get_privatekey($pem);
openssl_sign($body, $raw_sign, $mch_private_key, 'sha256WithRSAEncryption'); openssl_sign($body, $raw_sign, $mch_private_key, 'sha256WithRSAEncryption');
return base64_encode($raw_sign); return base64_encode($raw_sign);
} }
/** /**
* @param $json * @param $json
* @param $body * @param $body
* @return array * @return array
*/ */
private function createResponse($json, $body): array private function createResponse($json, $body): array
{ {
$responseArray['appId'] = $body['appid']; $responseArray['appId'] = $body['appid'];
$responseArray['timeStamp'] = (string)time(); $responseArray['timeStamp'] = (string)time();
$responseArray['nonceStr'] = Help::random(32); $responseArray['nonceStr'] = Help::random(32);
$responseArray['package'] = "prepay_id=" . $json['prepay_id']; $responseArray['package'] = "prepay_id=" . $json['prepay_id'];
$responseBody = $responseArray['appId'] . PHP_EOL . $responseArray['timeStamp'] . PHP_EOL . $responseArray['nonceStr'] . PHP_EOL . $responseArray['package'] . PHP_EOL; $responseBody = $responseArray['appId'] . PHP_EOL . $responseArray['timeStamp'] . PHP_EOL . $responseArray['nonceStr'] . PHP_EOL . $responseArray['package'] . PHP_EOL;
$responseArray['signType'] = 'RSA'; $responseArray['signType'] = 'RSA';
$responseArray['signBody'] = $responseBody; $responseArray['signBody'] = $responseBody;
$responseArray['paySign'] = $this->openssl_signature($responseBody); $responseArray['paySign'] = $this->openssl_signature($responseBody);
$responseArray['prepay_id'] = $json['prepay_id']; $responseArray['prepay_id'] = $json['prepay_id'];
return $responseArray; return $responseArray;
} }
/** /**
* @param $associatedData * @param $associatedData
* @param $nonceStr * @param $nonceStr
* @param $ciphertext * @param $ciphertext
* @return bool|string * @return bool|string
*/ */
public function decryptToString($associatedData, $nonceStr, $ciphertext): bool|string public function decryptToString($associatedData, $nonceStr, $ciphertext): bool|string
{ {
$ciphertext = \base64_decode($ciphertext); $ciphertext = \base64_decode($ciphertext);
if (strlen($ciphertext) <= AUTH_TAG_LENGTH_BYTE) { if (strlen($ciphertext) <= AUTH_TAG_LENGTH_BYTE) {
return FALSE; return FALSE;
} }
if (function_exists('\sodium\crypto_aead_aes256gcm_is_available') && crypto_aead_aes256gcm_is_available()) { if (function_exists('\sodium\crypto_aead_aes256gcm_is_available') && crypto_aead_aes256gcm_is_available()) {
return crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, 'XGwwZbmMXy6sD5w0IrxfaBHLl7b7jCaR'); return crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, 'XGwwZbmMXy6sD5w0IrxfaBHLl7b7jCaR');
} }
if (function_exists('\Sodium\crypto_aead_aes256gcm_is_available') && crypto_aead_aes256gcm_is_available()) { if (function_exists('\Sodium\crypto_aead_aes256gcm_is_available') && crypto_aead_aes256gcm_is_available()) {
return crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, 'XGwwZbmMXy6sD5w0IrxfaBHLl7b7jCaR'); return crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, 'XGwwZbmMXy6sD5w0IrxfaBHLl7b7jCaR');
} }
if (PHP_VERSION_ID >= 70100 && in_array('aes-256-gcm', \openssl_get_cipher_methods())) { if (PHP_VERSION_ID >= 70100 && in_array('aes-256-gcm', \openssl_get_cipher_methods())) {
$ctext = substr($ciphertext, 0, -AUTH_TAG_LENGTH_BYTE); $ctext = substr($ciphertext, 0, -AUTH_TAG_LENGTH_BYTE);
$authTag = substr($ciphertext, -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); 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'); throw new \RuntimeException('AEAD_AES_256_GCM需要PHP 7.1以上或者安装libsodium-php');
} }
} }