微信支付回调 敏感信息解密 v3 php
今天博主用了一波微信的v3版本的支付,支付成功后发现回调跟v2的完全不一样,于是去看了了一波v3的文档,发现信息是经过加密的,需要解密才能获取的到
但是最悲催的是文档上没写怎么解密的,经过了一下午的百度,找论坛,终于找到了文档地址,成功的拿到了我想要的信息,记录分享一波
1.支付成功,拿到回调信息后,转成数组后信息如下
$xml = ['id' => 'xxx', 'create_time' => '2020-08-19T12:16:56+08:00', 'resource_type' => 'xxx', 'event_type' => 'TRANSACTION.SUCCESS', 'summary' => '支付成功', 'resource' => [ 'original_type' => 'xxxx', 'algorithm' => 'AEAD_AES_256_GCM', 'ciphertext' => 'xxx', 'associated_data' => 'xxxx', 'nonce' => 'xxx',] ];
2.你想要的信息在 resource 里面,但是是经过加密的,接下来需要解密一波
先创建一个 AesUtil.php,复制以下代码粘进去
<?php class AesUtil { /** * AES key * * @var string */ private $aesKey; const KEY_LENGTH_BYTE = 32; const AUTH_TAG_LENGTH_BYTE = 16; /** * Constructor */ public function __construct($aesKey) { if (strlen($aesKey) != self::KEY_LENGTH_BYTE) { throw new InvalidArgumentException('无效的ApiV3Key,长度应为32个字节'); } $this->aesKey = $aesKey; } /** * Decrypt AEAD_AES_256_GCM ciphertext * * @param string $associatedData AES GCM additional authentication data * @param string $nonceStr AES GCM nonce * @param string $ciphertext AES GCM cipher text * * @return string|bool Decrypted string on success or FALSE on failure */ public function decryptToString($associatedData, $nonceStr, $ciphertext) { $ciphertext = \base64_decode($ciphertext); if (strlen($ciphertext) <= self::AUTH_TAG_LENGTH_BYTE) { return false; } // ext-sodium (default installed on >= PHP 7.2) if (function_exists('\sodium_crypto_aead_aes256gcm_is_available') && \sodium_crypto_aead_aes256gcm_is_available()) { return \sodium_crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $this->aesKey); } // ext-libsodium (need install libsodium-php 1.x via pecl) if (function_exists('\Sodium\crypto_aead_aes256gcm_is_available') && \Sodium\crypto_aead_aes256gcm_is_available()) { return \Sodium\crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $this->aesKey); } // openssl (PHP >= 7.1 support AEAD) if (PHP_VERSION_ID >= 70100 && in_array('aes-256-gcm', \openssl_get_cipher_methods())) { $ctext = substr($ciphertext, 0, -self::AUTH_TAG_LENGTH_BYTE); $authTag = substr($ciphertext, -self::AUTH_TAG_LENGTH_BYTE); return \openssl_decrypt($ctext, 'aes-256-gcm', $this->aesKey, \OPENSSL_RAW_DATA, $nonceStr, $authTag, $associatedData); } throw new \RuntimeException('AEAD_AES_256_GCM需要PHP 7.1以上或者安装libsodium-php'); } }
3.接下来就是解密了
var_dump((new AesUtil('你的APIv3秘钥'))->decryptToString($xml['resource']['associated_data'],$xml['resource']['nonce'],$xml['resource']['ciphertext']));
文档地址:https://wechatpay-api.gitbook.io/wechatpay-api-v3/qian-ming-zhi-nan-1/zheng-shu-he-hui-tiao-bao-wen-jie-mi