Browse Source

得润宝

cqp 1 week ago
parent
commit
f969c29421
1 changed files with 11 additions and 15 deletions
  1. 11 15
      app/Service/DingTalkCrypto.php

+ 11 - 15
app/Service/DingTalkCrypto.php

@@ -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,