z761003 发表于 2023-8-17 12:48:08

发钉钉群机器人消息碰到的问题

本帖最后由 z761003 于 2023-8-17 12:50 编辑

为了发钉钉群机器人消息,按钉钉要求把时间戳连接签名一起,先SHA256加密,再base64加密,再UrlEncode。因多次测试失败,我把这三个过程用PY代码测试通过,然后分别比对,发现PY和AU3 在SHA256 加密后都显示结果为
\xc4\xd9\xcdo\xcf]\x11\xa433\xd0\xb0jkgt?\xb0p\x98\xc5\x8f\x97\\\xebH\xf8M\xd3\x03\xdc\x03
但对这串玩意在AU3里直接进行Base64加密得到的是w4TDmcONb8OPXRHCpDMzw5DCsGprZ3Q/wrBwwpjDhcKPwpdcw6tIw7hNw5MDw5wD
而PY里得到的是 xNnNb89dEaQzM9CwamtndD+wcJjFj5dc60j4TdMD3AM=
PY里的是正确的,可以成功发消息。到这以为问题出在PY和AU3的Base64可能加密不同,要命的是,却又出了另外个事实:单独用py和AU3里的Base64函数分别对某一串字符串加密的话,结果又是一样的
比如对 a123?加密,同样都是 YTEyMz8=换用更复杂更长的串,也是一样的
所以就迷糊了,希望大伽指点下,问题到底在哪,是不是SHA256后出的这一长串带反斜杠的,不能直接base64还是啥。。

Global $HMAC_RAWFORM = 0, $HMAC_HEXFORM = 1, $HMAC_PYFORM = 2



Local $sSecret="SECee08ec11058d84f58649214a037ebeb6d31f390adbe48336135927db595aa7f3"

Local $timestamp="1692243595561"

Local $sMessage=$timestamp&@LF&$sSecret

Local $stringToSign=_HashHMAC("SHA256", $sMessage, $sSecret, $HMAC_PYFORM)

CW("SHA256:"&$stringToSign)

$stringToSign=Base64($stringToSign)

CW("Base64;"&$stringToSign)


<blockquote>Func base64($str,$p=1)AU3里执行返回

PY里执行返回


绿色风 发表于 2023-8-18 13:01:24

看下,还能用不 https://www.jianyiit.com/post-390.html

z761003 发表于 2023-8-19 14:39:10

绿色风 发表于 2023-8-18 13:01
看下,还能用不 https://www.jianyiit.com/post-390.html

风哥你这是发限制关键字的消息可以,就是不需要Secret密钥的,但发的消息内容必须带有关键词,有限制,谢谢风哥回复

gyp2000 发表于 2023-8-20 23:53:56

是编码方式选错了。
测试通过。

Global $HMAC_RAWFORM = 0, $HMAC_HEXFORM = 1, $HMAC_PYFORM = 2
Local $sSecret = "SECee08ec11058d84f58649214a037ebeb6d31f390adbe48336135927db595aa7f3"
Local $timestamp = "1692243595561"
Local $sMessage = $timestamp & @LF & $sSecret
Local $stringToSign = _HashHMAC("SHA256", $sMessage, $sSecret, $HMAC_RAWFORM)

CW("SHA256: " & String($stringToSign))
$stringToSign = _Base64Encode($stringToSign)
CW("Base64: " & $stringToSign)

Func CW($string)
        ConsoleWrite($string & @CRLF)
EndFunc   ;==>CW

Func _WinAPI_Base64Decode($sB64String)
        Local $aCrypt = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryA", "str", $sB64String, "dword", 0, "dword", 1, "ptr", 0, "dword*", 0, "ptr", 0, "ptr", 0)
        If @error Or Not $aCrypt Then Return SetError(1, 0, "")
        Local $tBuffer = DllStructCreate("byte[" & $aCrypt & "]")
        $aCrypt = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryA", "str", $sB64String, "dword", 0, "dword", 1, "struct*", $tBuffer, "dword*", $aCrypt, "ptr", 0, "ptr", 0)
        If @error Or Not $aCrypt Then Return SetError(2, 0, "")
        Return DllStructGetData($tBuffer, 1)
EndFunc   ;==>_WinAPI_Base64Decode

Func _HashHMAC($sAlgorithm, $bData, $bKey, $iOutputForm = $HMAC_HEXFORM)
        Local $oHashHMACErrorHandler = ObjEvent("AutoIt.Error", "_HashHMACErrorHandler")
        Local $oHMAC = ObjCreate("System.Security.Cryptography.HMAC" & $sAlgorithm)
        If @error Then SetError(1, 0, "")
        $oHMAC.key = Binary($bKey)
        Local $bHash = $oHMAC.ComputeHash_2(Binary($bData))
        Local $sHex = StringLower(StringMid($bHash, 3))
        Switch $iOutputForm
                Case $HMAC_RAWFORM
                        Return $bHash
                Case $HMAC_HEXFORM
                        Return $sHex
                Case $HMAC_PYFORM
                        Local $c, $sPy
                        For $i = 1 To BinaryLen($bHash)
                                $c = BinaryMid($bHash, $i, 1)
                                If $c < 0x20 Or $c > 0x7E Then
                                        $sPy &= "\x" & StringLower(Hex($c, 2))
                                Else
                                        $sPy &= ($c = 0x5C ? "\\" : Chr($c))
                                EndIf
                        Next
                        Return $sPy
                Case Else
                        Return SetError(2)
        EndSwitch
EndFunc   ;==>_HashHMAC

Func _Base64Encode($input)
        If Not IsBinary($input) Then $input = Binary($input)
        Local $struct = DllStructCreate("byte[" & BinaryLen($input) & "]")
        DllStructSetData($struct, 1, $input)
        Local $strc = DllStructCreate("int")
        Local $a_Call = DllCall("Crypt32.dll", "int", "CryptBinaryToString", _
                        "ptr", DllStructGetPtr($struct), _
                        "int", DllStructGetSize($struct), _
                        "int", 1 + 0x40000000, _
                        "ptr", 0, _
                        "ptr", DllStructGetPtr($strc))
        If @error Or Not $a_Call Then
                Return SetError(1, 0, "") ; error calculating the length of the buffer needed
        EndIf
        Local $a = DllStructCreate("char[" & DllStructGetData($strc, 1) & "]")
        $a_Call = DllCall("Crypt32.dll", "int", "CryptBinaryToString", _
                        "ptr", DllStructGetPtr($struct), _
                        "int", DllStructGetSize($struct), _
                        "int", 1 + 0x40000000, _
                        "ptr", DllStructGetPtr($a), _
                        "ptr", DllStructGetPtr($strc))

        If @error Or Not $a_Call Then
                Return SetError(2, 0, "") ; error encoding
        EndIf
        Return DllStructGetData($a, 1)
EndFunc   ;==>_Base64Encode


运行结果:
SHA256: 0xC4D9CD6FCF5D11A43333D0B06A6B67743FB07098C58F975CEB48F84DD303DC03
Base64: xNnNb89dEaQzM9CwamtndD+wcJjFj5dc60j4TdMD3AM=

z761003 发表于 2023-8-23 07:27:56

gyp2000 发表于 2023-8-20 23:53
是编码方式选错了。
测试通过。



非常 感谢,论坛里真是高手如云哪
页: [1]
查看完整版本: 发钉钉群机器人消息碰到的问题