|
@@ -16,7 +16,7 @@ class DingTalkCrypto
|
|
|
/**
|
|
|
* 解密钉钉事件回调消息
|
|
|
*
|
|
|
- * @param string $signature URL参数 signature
|
|
|
+ * @param string $msgSignature URL参数 msg_signature
|
|
|
* @param string $timestamp URL参数 timestamp
|
|
|
* @param string $nonce URL参数 nonce
|
|
|
* @param string $encrypt 消息体 encrypt
|
|
@@ -24,33 +24,30 @@ class DingTalkCrypto
|
|
|
*/
|
|
|
public function decryptMsg(string $msgSignature, string $timestamp, string $nonce, string $encrypt)
|
|
|
{
|
|
|
- // 验签
|
|
|
- $tmpArr = [$this->token, $timestamp, $nonce, $encrypt];
|
|
|
- sort($tmpArr, SORT_STRING);
|
|
|
- $tmpStr = implode('', $tmpArr);
|
|
|
- $hash = sha1($tmpStr);
|
|
|
+ // 1. 验签 (官方要求 token + timestamp + nonce + encrypt 顺序拼接)
|
|
|
+ $hash = sha1($this->token . $timestamp . $nonce . $encrypt);
|
|
|
if ($hash !== $msgSignature) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- // AES 解密
|
|
|
- $aesKey = base64_decode($this->encodingAesKey . '='); // 补足 padding
|
|
|
+ // 2. AES 解密
|
|
|
+ $aesKey = base64_decode($this->encodingAesKey);
|
|
|
$iv = substr($aesKey, 0, 16);
|
|
|
$cipherText = base64_decode($encrypt);
|
|
|
$decrypted = openssl_decrypt($cipherText, 'AES-256-CBC', $aesKey, OPENSSL_ZERO_PADDING, $iv);
|
|
|
if ($decrypted === false) return false;
|
|
|
|
|
|
- // 去掉 padding
|
|
|
+ // 3. 去掉 PKCS#7 padding
|
|
|
$decrypted = $this->pkcs7Unpad($decrypted);
|
|
|
|
|
|
- // 去掉前16位随机字符串
|
|
|
+ // 4. 去掉前16位随机字符串
|
|
|
$content = substr($decrypted, 16);
|
|
|
|
|
|
- // 读取消息长度
|
|
|
+ // 5. 读取消息长度(4字节 network order)
|
|
|
$lenList = unpack("N", substr($content, 0, 4));
|
|
|
$jsonLen = $lenList[1];
|
|
|
|
|
|
- // 获取 JSON
|
|
|
+ // 6. 获取 JSON
|
|
|
$json = substr($content, 4, $jsonLen);
|
|
|
|
|
|
return json_decode($json, true);
|
|
@@ -68,7 +65,7 @@ class DingTalkCrypto
|
|
|
{
|
|
|
$random16 = $this->getRandomStr(16);
|
|
|
$msgLenBin = pack("N", strlen($replyMsg));
|
|
|
- $corpId = ''; // 不需要corpId
|
|
|
+ $corpId = ''; // 不需要 corpId
|
|
|
|
|
|
$plain = $random16 . $msgLenBin . $replyMsg . $corpId;
|
|
|
|
|
@@ -85,8 +82,7 @@ class DingTalkCrypto
|
|
|
$encryptBase64 = base64_encode($encrypted);
|
|
|
|
|
|
// 计算 msg_signature
|
|
|
- $signatureStr = $this->token . $timestamp . $nonce . $encryptBase64;
|
|
|
- $msgSignature = sha1($signatureStr);
|
|
|
+ $msgSignature = sha1($this->token . $timestamp . $nonce . $encryptBase64);
|
|
|
|
|
|
return [
|
|
|
'msg_signature' => $msgSignature,
|