安裝官方文件說明的,要先獲取平臺證照列表,然後再進行解密,獲取方法如下:
圖片中User-Agent後面備註的使用者代理(https://zh.wikipedia.org/wiki/User_agent)不知道是幹嘛的..
按照之前的簽名方法,最後獲得Authiorization值,放到header頭中,header頭引數如下:
$headers[] = 'Content-Type:application/json';
$headers[] = 'Accept:application/json';
$headers[] = 'User-Agent:'.$_SERVER['HTTP_USER_AGENT'];
$headers[] = 'Authorization:WECHATPAY2-SHA256-RSA2048 '.$token;
獲得證照列表如下:
為方便後面說明問題,我這裡把data資料整個貼出來
{
"data": [
{
"effective_time": "2020-08-20T14:59:52+08:00",
"encrypt_certificate": {
"algorithm": "AEAD_AES_256_GCM",
"associated_data": "certificate",
"ciphertext": "io6eoAWJH1rb8GJ04aJ6LBUu059j2VhWpoi3Odaez1ngOHVdNPH4bHRLRji6Bdb3QTYWgF0L9Zjdjc/Zbt5dC10ixd8KlB1ZvRDaJ4nSSmVdJ0L92i3ORHJmKHsWVbt8+ZaM2Kg+vfDLRqnoZ4/YnL4PPi/U5bXovvFIzvOcvb6u6hXdq8+Ad7Ms4iOilKJyOiDNMci7HlC+h4elp5UvbebITMEG4OdzexHi8PEcrcRYEODFygzd0SDvOj5sQGjRTqtpA71o55gD0AKTtud3SH856y/N/2GIcmHArB7U5Q5zXQQQ8Fz14KA5bas7snqMMlqv/6c4aFsQjA1Di2Dm1+/E2aMHWn4UpDAohV4X5+MSHHfDdtsIfnvsgKwLjzTKXSe2d/FEjPYgtf/p6GwptGTJFbrk4octETAMpVIE8c2lUq6E8ekf+PqCYLT5njin8z6CBK/7PC4DrR195vTf/pOikyEV6fqc3/iety39y2LCgvDzL/0rz40thvHz4uBNqaxtnTo2SJlouR4D3qi+dmjO4XMWyPAZXpxxboV9PCQAufSGF65tSO8pRGPZiD76mNCyRi8nYeZtL3HFg4afXZeObAzQMJnxaMRsn7jObS+pibgbK45oUfmuoq8yEBUuvqvf5O3JPqKyI4QVqmYg0H07U9ueCWR/iHlsEsSwMG9Hjy4SvW5wPGYGdW9mio21YOl1uucTkS2b+szILnSaJ3oWoTb417qjoGI6Bt6ZWRRZAOmJsJGkzDTv1din0Wg/vRUpFFS/HI466E6yjEbORC8sPL1oze9qx2KsgML6GcUABdWcUXXqzScXxhFufeIkdqj2hG+I+ElNwlpuY/FKd6pqM29BP5up+EtazsABMjEb3e+WHbrwzmzY5c+uRwozd/Z15SKjYtgzOTK0HKbmyOBccA+5moFIt42Alwci3UIUYc5KStdywT42iCc++FtE+Dzu5R0spFFnEj9g9gbw8HzWWL2SCHoYOSsyFegz1QGYiJYAILdIle0IyFD2+PZGNbcdXzE6y2VS6GREhnRmn6QMfb83L7xUTQQf43NdsgXLb+XHGwtn0tZqH+vsMKn1hi0wmelqIsxHv+CvFKg/f7HoRd52vZ6i+uIfXE2nR1dHbygMtlZan47D45g3ZT+lI+0ECojFQI9IuGxRP35n3Sv4yjEvSIbs3+BTEYWZs6gmCyyK2vIm58j8TkTtuyGC5s4ExKl2o3Qfw1mUUg6WKzfnc4iup9Q8JsRNyH+/ra4FvATODvRZakAqlsaV079E+FRu73D+4lq92ZBST/XnGW2jrxuOxGsI2Q9AHiOZWoIFXVZp8DtBaFj/hGEAgN0atv53At/KdrM5Y+x7zx6v9NGOKkFnkw7LuJsARwj6pVSoh2cOQ9tJzCeeSQF985+q66Bmq6Kq51oMnyEzMe+HoOxeUEcTvLfCwteAcJzG/AkZwkwvnXLCcRBpc4ZEEfJtzwSasqdYapE/jexHG1fCQXcuqtdJUeXtxIBBMeTwLEBwed6pGjNw1tmDyNRN2fOzPX7FXbjgek8CJZC4oSStp7tuMIYkoV0RbmDBiSXV0QdOQ5vXgZw4WPalWv32gYhXG8yg8EE6MbPP4Pl8TpFm1CfCpWz2MVS5PyzY/2+lMfGuE3QK5IURbbZsILZJSY6e9TS9stquZEm4hnYB1syzTIf2+dL3GoFOQ45risIUcO68pTo4uBvKm2elpYTtiiQuwxj+0aKwLAilCGy3khNEdZfreWQaTuM///Pu5CkuBbCCYoevJEQnvX7U1HWRDJ1BjVE5Dqc23m2ThQ4exgihvikA4D2RnvGMpBhSJ71kD1kuPMCw+pQLvPFTKS/lOsH9cDZR+Gulvk29TTZ01EtjaQCbwrn6YQ==",
"nonce": "aacc84fbf399"
},
"expire_time": "2025-08-19T14:59:52+08:00",
}
]
}
下面開始看官方文件裡證照和回撥報文解密的部分,看到官方有提供整個解密操作的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);
$rs = \openssl_decrypt($ctext, 'aes-256-gcm', $this->aesKey, \OPENSSL_RAW_DATA, $nonceStr,
$authTag, $associatedData);
var_dump($rs);exit; // 列印出解密結果
return $rs;
}
throw new \RuntimeException('AEAD_AES_256_GCM需要PHP 7.1以上或者安裝libsodium-php');
}
}
這個類很簡單,主要是用到3個引數:$associatedData, $nonceStr, $ciphertext
,還有一個初始化類的時候用到的API V3的祕鑰,這個是在商戶後臺的API安全裡配置的。
我直接把官方提供的這個類原封不動的拷過來,然後在控制器方法中引用這個類:
$aesutil = new AesUtilController($apiv3Key);
$rs = $aesutil->decryptToString($associatedData,$nonce,$ciphertext);
四個引數:
$apiv3Key 我在商戶後臺-API安全裡配置的祕鑰;
$associatedData 就是上面data資料裡的associated_data值”certificate”;
$nonce 就是上面data資料裡的nonce值”aacc84fbf399”;
$ciphertext 就是上面data資料裡的nonce值”ciphertext”;
全部配置好後,執行測試,返回bool(false)
,解密失敗!
想不明白,問題出在哪裡,一共就4個引數,$apiv3Key是固定值,不會有問題,其他3個引數都是從平臺api獲取的,應該也不會錯的啊?
嘗試在線上base64解碼”ciphertext”的值,發現獲取的是亂碼:
一臉懵逼,不知道是本來就應該是亂碼還是我獲取的”ciphertext”值是有問題的?又或者是我中間漏了什麼操作?
本作品採用《CC 協議》,轉載必須註明作者和本文連結