yj
2026-03-31 033d919018b3a3e12755f008c0b9093364942512
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
o
žskh5.ã@sdZddlZddlZddlZddlZddlZddlZddlmZddl    m
m Z ddl Z ddlZdZdZdZdZdZdZd    Zd
Zd Zd Zd ZdZdZ    Gdd„deƒZefdd„ZGdd„dƒZGdd„dƒZ Gdd„dƒZ!Gdd„dƒZ"Gdd„de#ƒZ$Gdd„de#ƒZ%dS) uw å¯¹ä¼ä¸šå¾®ä¿¡å‘送给企业后台的消息加解密示例代码.
@copyright: Copyright (c) 1998-2014 Tencent Inc.
 
éN)ÚAESi¿cÿÿi¾cÿÿi½cÿÿi¼cÿÿi»cÿÿiºcÿÿi¹cÿÿi¸cÿÿi·cÿÿi¶cÿÿiµcÿÿi´cÿÿc@s eZdZdS)ÚFormatExceptionN)Ú__name__Ú
__module__Ú __qualname__©rrú:E:\project\python\wecom-dify-bridge\wecom\WXBizMsgCrypt.pyr(srcCs||ƒ‚)z"my define raise exception functionr)ÚmessageÚexception_classrrrÚthrow_exception,sr c@seZdZdZdd„ZdS)ÚSHA1u'计算企业微信的消息签名接口c    
Cs~z||||g}| ¡t ¡}| d |¡ ¡¡t| ¡fWSty>}zt     
¡}|  |¡t dfWYd}~Sd}~ww)uÍ用SHA1算法生成安全签名
        @param token:  ç¥¨æ®
        @param timestamp: æ—¶é—´æˆ³
        @param encrypt: å¯†æ–‡
        @param nonce: éšæœºå­—符串
        @return: å®‰å…¨ç­¾å
        ÚN) ÚsortÚhashlibÚsha1ÚupdateÚjoinÚencodeÚWXBizMsgCrypt_OKÚ    hexdigestÚ    ExceptionÚloggingÚ    getLoggerÚerrorÚ$WXBizMsgCrypt_ComputeSignature_Error)    ÚselfÚtokenÚ    timestampÚnonceÚencryptZsortlistÚshaÚeÚloggerrrrÚgetSHA14s 
€ýz SHA1.getSHA1N)rrrÚ__doc__r#rrrrr 1s r c@ó$eZdZdZdZdd„Zdd„ZdS)ÚXMLParseõH提供提取消息格式中的密文及生成回复消息格式的接口zÁ<xml>
<Encrypt><![CDATA[%(msg_encrypt)s]]></Encrypt>
<MsgSignature><![CDATA[%(msg_signaturet)s]]></MsgSignature>
<TimeStamp>%(timestamp)s</TimeStamp>
<Nonce><![CDATA[%(nonce)s]]></Nonce>
</xml>c
Cs`zt |¡}| d¡}t|jfWSty/}zt ¡}| |¡t    dfWYd}~Sd}~ww)u”提取出xml数据包中的加密消息
        @param xmltext: å¾…提取的xml字符串
        @return: æå–出的加密消息字符串
        ZEncryptN)
ÚETÚ
fromstringÚfindrÚtextrrrrÚWXBizMsgCrypt_ParseXml_Error)rZxmltextZxml_treerr!r"rrrÚextractSs
 
 
€ýzXMLParse.extractcCs||||dœ}|j|}|S)uá生成xml消息
        @param encrypt: åŠ å¯†åŽçš„æ¶ˆæ¯å¯†æ–‡
        @param signature: å®‰å…¨ç­¾å
        @param timestamp: æ—¶é—´æˆ³
        @param nonce: éšæœºå­—符串
        @return: ç”Ÿæˆçš„xml字符串
        )Ú msg_encryptZmsg_signaturetrr)ÚAES_TEXT_RESPONSE_TEMPLATE)rrÚ    signaturerrÚ    resp_dictZresp_xmlrrrÚgenerateas    ü
zXMLParse.generateN)rrrr$r/r-r2rrrrr&Hs
 r&c@s eZdZdZdd„Zdd„ZdS)Ú    JsonParser'c
Cs\zt |¡}|d}t|fWSty-}zt ¡}| |¡tdfWYd}~Sd}~ww)uœæå–出json数据包中的加密消息
        @param json_data_str: å¾…提取的json字符串
        @return: æå–出的加密消息字符串
        rN)ÚjsonÚloadsrrrrrÚWXBizMsgCrypt_ParseJson_Error)rZ json_data_strZjson_data_dictrr!r"rrrr-vs
 
 
€ýzJsonParse.extractcCs||||dœ}|S)uæç”Ÿæˆjson消息
        @param encrypt: åŠ å¯†åŽçš„æ¶ˆæ¯å¯†æ–‡
        @param msgsignature: å®‰å…¨ç­¾å
        @param timestamp: æ—¶é—´æˆ³
        @param nonce: éšæœºå­—符串
        @return: ç”Ÿæˆçš„json字符串
        )rZ msgsignaturerrr)rrr0rrr1rrrr2„s     üzJsonParse.generateN)rrrr$r-r2rrrrr3ss r3c@r%)Ú PKCS7Encoderu)提供基于PKCS7算法的加解密接口é cCs>t|ƒ}|j||j}|dkr|j}t|ƒ}||| ¡S)u˜ å¯¹éœ€è¦åŠ å¯†çš„æ˜Žæ–‡è¿›è¡Œå¡«å……è¡¥ä½
        @param text: éœ€è¦è¿›è¡Œå¡«å……补位操作的明文
        @return: è¡¥é½æ˜Žæ–‡å­—符串
        r)ÚlenÚ
block_sizeÚchrr)rr+Z text_lengthZ amount_to_padÚpadrrrršs zPKCS7Encoder.encodecCs.t|dƒ}|dks|dkrd}|d| …S)uŠåˆ é™¤è§£å¯†åŽæ˜Žæ–‡çš„补位字符
        @param decrypted: è§£å¯†åŽçš„æ˜Žæ–‡
        @return: åˆ é™¤è¡¥ä½å­—符后的明文
        éÿÿÿÿér8rN)Úord)rZ    decryptedr<rrrÚdecode¨s zPKCS7Encoder.decodeN)rrrr$r:rr@rrrrr7•s
 r7c@s0eZdZdZdd„Zdd„Zdd„Zdd    „Zd
S) ÚPrpcryptu<提供接收和推送给企业微信消息的加解密接口cCs||_tj|_dS©N)ÚkeyrZMODE_CBCÚmode)rrCrrrÚ__init__¶s zPrpcrypt.__init__c
Cs¸| ¡}| ¡t dt t|ƒ¡¡|| ¡}tƒ}| |¡}t     |j
|j |j
dd…¡}z |  |¡}t t |¡fWSty[}zt ¡}| |¡tdfWYd}~Sd}~ww)us对明文进行加密
        @param text: éœ€è¦åŠ å¯†çš„æ˜Žæ–‡
        @return: åŠ å¯†å¾—åˆ°çš„å­—ç¬¦ä¸²
        ÚINé)rÚget_random_strÚstructÚpackÚsocketÚhtonlr9r7rÚnewrCrDrrÚbase64Ú    b64encoderrrrÚWXBizMsgCrypt_EncryptAES_Error)rr+Ú    receiveidÚpkcs7ÚcryptorZ
ciphertextr!r"rrrr½s*
 
 
€ýzPrpcrypt.encryptc
Cs&zt |j|j|jdd…¡}| t |¡¡}Wnty7}zt     ¡}| 
|¡t dfWYd}~Sd}~wwz,|d}|d| …}t   t d|dd…¡d¡}    |d|    d…}
||    dd…} Wntyƒ}zt     ¡}| 
|¡tdfWYd}~Sd}~ww|  d¡|krtdfSd|
fS)u|对解密后的明文进行补位删除
        @param text: å¯†æ–‡
        @return: åˆ é™¤å¡«å……补位后的明文
        NrGr=rFérÚutf8)rrMrCrDÚdecryptrNÚ    b64decoderrrrÚWXBizMsgCrypt_DecryptAES_ErrorrKÚntohlrIÚunpackÚWXBizMsgCrypt_IllegalBufferr@Ú"WXBizMsgCrypt_ValidateCorpid_Error) rr+rQrSZ
plain_textr!r"r<ÚcontentZxml_lenÚ xml_contentZfrom_receiveidrrrrVÔs0
€ý
€ýzPrpcrypt.decryptcCstt dd¡ƒ ¡S)uD éšæœºç”Ÿæˆ16位字符串
        @return: 16位字符串
        lIú5lÿ_É)ÚstrÚrandomÚrandintr)rrrrrHôszPrpcrypt.get_random_strN)rrrr$rErrVrHrrrrrA³s   rAc@s.eZdZdd„Zdd„Zd
dd„Zdd    „ZdS) Ú WXBizMsgCryptcCsJzt |d¡|_t|jƒdksJ‚Wn    tdtƒY||_||_dS)Nú=r8z![error]: EncodingAESKey unvalid !)rNrWrCr9r rÚm_sTokenÚ m_sReceiveId)rZsTokenZsEncodingAESKeyZ
sReceiveIdrrrrEýs 
zWXBizMsgCrypt.__init__c
Cs`tƒ}| |j|||¡\}}|dkr|dfS||kstdfSt|jƒ}| ||j¡\}}    ||    fS©Nr)r r#rdÚ%WXBizMsgCrypt_ValidateSignature_ErrorrArCrVre)
rÚ sMsgSignatureÚ
sTimeStampÚsNonceZsEchoStrrÚretr0ÚpcZ sReplyEchoStrrrrÚ    VerifyURLs
zWXBizMsgCrypt.VerifyURLNc
Cs”t|jƒ}| ||j¡\}}| d¡}|dkr|dfS|dur'ttt ¡ƒƒ}tƒ}|     |j
|||¡\}}|dkr=|dfSt ƒ}    ||      ||||¡fS)NrUr) rArCrrer@r_ÚintÚtimer r#rdr3r2)
rZ    sReplyMsgrjrrlrkrrr0Ú    jsonParserrrÚ
EncryptMsgs
 
zWXBizMsgCrypt.EncryptMsgc Cs„tƒ}| |¡\}}|dkr|dfStƒ}| |j|||¡\}}    |dkr(|dfS|    |ks0tdfSt|jƒ}
|
 ||j    ¡\}} || fSrf)
r3r-r r#rdrgrArCrVre) rZ    sPostDatarhrirjrprkrrr0rlr^rrrÚ
DecryptMsg0s    
zWXBizMsgCrypt.DecryptMsgrB)rrrrErmrqrrrrrrrbûs
 
rb)&r$rrNr`rrorIZ Crypto.CipherrZxml.etree.cElementTreeÚetreeZ cElementTreer(rKr4rrgr,rZWXBizMsgCrypt_IllegalAesKeyr\rPrXr[Z WXBizMsgCrypt_EncodeBase64_ErrorZ WXBizMsgCrypt_DecodeBase64_ErrorZ WXBizMsgCrypt_GenReturnXml_Errorr6rrr r r&r3r7ÚobjectrArbrrrrÚ<module>sB  +"H