#pragma once #include <string> #include <stdint.h> #include "tinyxml2\tinyxml2.h" namespace Tencent { static const unsigned int kAesKeySize = 32; static const unsigned int kAesIVSize = 16; static const unsigned int kEncodingKeySize = 43; static const unsigned int kRandEncryptStrLen = 16; static const unsigned int kMsgLen = 4; static const unsigned int kMaxBase64Size = 1000000000; enum WXBizMsgCryptErrorCode { WXBizMsgCrypt_OK = 0, WXBizMsgCrypt_ValidateSignature_Error = -40001, WXBizMsgCrypt_ParseXml_Error = -40002, WXBizMsgCrypt_ComputeSignature_Error = -40003, WXBizMsgCrypt_IllegalAesKey = -40004, WXBizMsgCrypt_ValidateCorpid_Error = -40005, WXBizMsgCrypt_EncryptAES_Error = -40006, WXBizMsgCrypt_DecryptAES_Error = -40007, WXBizMsgCrypt_IllegalBuffer = -40008, WXBizMsgCrypt_EncodeBase64_Error = -40009, WXBizMsgCrypt_DecodeBase64_Error = -40010, WXBizMsgCrypt_GenReturnXml_Error = -40011, }; class WXBizMsgCrypt { public: //¹¹Ô캯Êý // @param sToken: Æóҵ΢Ðźǫ́£¬¿ª·¢ÕßÉèÖõÄToken // @param sEncodingAESKey: Æóҵ΢Ðźǫ́£¬¿ª·¢ÕßÉèÖõÄEncodingAESKey // @param sCorpid: ÆóÒµºÅµÄcorpid WXBizMsgCrypt(const std::string &sToken, const std::string &sEncodingAESKey, const std::string &sCorpid) :m_sToken(sToken), m_sEncodingAESKey(sEncodingAESKey),m_sCorpid(sCorpid) { } //ÑéÖ¤URL // @param sMsgSignature: Ç©Ãû´®£¬¶ÔÓ¦URL²ÎÊýµÄmsg_signature // @param sTimeStamp: ʱ¼ä´Á£¬¶ÔÓ¦URL²ÎÊýµÄtimestamp // @param sNonce: Ëæ»ú´®£¬¶ÔÓ¦URL²ÎÊýµÄnonce // @param sEchoStr: Ëæ»ú´®£¬¶ÔÓ¦URL²ÎÊýµÄechostr // @param sReplyEchoStr: ½âÃÜÖ®ºóµÄechostr£¬µ±return·µ»Ø0ʱÓÐЧ // @return£º³É¹¦0£¬Ê§°Ü·µ»Ø¶ÔÓ¦µÄ´íÎóÂë int VerifyURL(const std::string& sMsgSignature, const std::string& sTimeStamp, const std::string& sNonce, const std::string& sEchoStr, std::string& sReplyEchoStr); // ¼ìÑéÏûÏ¢µÄÕæÊµÐÔ£¬²¢ÇÒ»ñÈ¡½âÃܺóµÄÃ÷ÎÄ // @param sMsgSignature: Ç©Ãû´®£¬¶ÔÓ¦URL²ÎÊýµÄmsg_signature // @param sTimeStamp: ʱ¼ä´Á£¬¶ÔÓ¦URL²ÎÊýµÄtimestamp // @param sNonce: Ëæ»ú´®£¬¶ÔÓ¦URL²ÎÊýµÄnonce // @param sPostData: ÃÜÎÄ£¬¶ÔÓ¦POSTÇëÇóµÄÊý¾Ý // @param sMsg: ½âÃܺóµÄÔÎÄ£¬µ±return·µ»Ø0ʱÓÐЧ // @return: ³É¹¦0£¬Ê§°Ü·µ»Ø¶ÔÓ¦µÄ´íÎóÂë int DecryptMsg(const std::string &sMsgSignature, const std::string &sTimeStamp, const std::string &sNonce, const std::string &sPostData, std::string &sMsg); //½«Æóҵ΢ÐŻظ´Óû§µÄÏûÏ¢¼ÓÃÜ´ò°ü // @param sReplyMsg:Æóҵ΢ÐÅ´ý»Ø¸´Óû§µÄÏûÏ¢£¬xml¸ñʽµÄ×Ö·û´® // @param sTimeStamp: ʱ¼ä´Á£¬¿ÉÒÔ×Ô¼ºÉú³É£¬Ò²¿ÉÒÔÓÃURL²ÎÊýµÄtimestamp // @param sNonce: Ëæ»ú´®£¬¿ÉÒÔ×Ô¼ºÉú³É£¬Ò²¿ÉÒÔÓÃURL²ÎÊýµÄnonce // @param sEncryptMsg: ¼ÓÃܺóµÄ¿ÉÒÔÖ±½Ó»Ø¸´Óû§µÄÃÜÎÄ£¬°üÀ¨msg_signature, timestamp, nonce, encryptµÄxml¸ñʽµÄ×Ö·û´®, // µ±return·µ»Ø0ʱÓÐЧ // return£º³É¹¦0£¬Ê§°Ü·µ»Ø¶ÔÓ¦µÄ´íÎóÂë int EncryptMsg(const std::string &sReplyMsg, const std::string &sTimeStamp, const std::string &sNonce, std::string &sEncryptMsg); int GetXmlField(const std::string & sPostData, const std::string & sField,std:: string &sEncryptMsg); private: std::string m_sToken; std::string m_sEncodingAESKey; std::string m_sCorpid; private: // AES CBC int AES_CBCEncrypt( const char * sSource, const uint32_t iSize, const char * sKey, unsigned int iKeySize, std::string * poResult ); int AES_CBCEncrypt( const std::string & objSource, const std::string & objKey, std::string * poResult ); int AES_CBCDecrypt( const char * sSource, const uint32_t iSize, const char * sKey, uint32_t iKeySize, std::string * poResult ); int AES_CBCDecrypt( const std::string & objSource, const std::string & objKey, std::string * poResult ); //base64 int EncodeBase64(const std::string sSrc, std::string & sTarget); int DecodeBase64(const std::string sSrc, std::string & sTarget); //genkey int GenAesKeyFromEncodingKey( const std::string & sEncodingKey, std::string & sAesKey); //signature int ComputeSignature(const std::string sToken, const std::string sTimeStamp, const std::string & sNonce, const std::string & sMessage, std::string & sSignature); int ValidateSignature(const std::string &sMsgSignature, const std::string &sTimeStamp, const std::string &sNonce, const std::string & sEncryptMsg); //get , set data void GenRandStr(std::string & sRandStr, uint32_t len); void GenNeedEncryptData(const std::string &sReplyMsg,std::string & sNeedEncrypt ); int SetOneFieldToXml(tinyxml2::XMLDocument * pDoc, tinyxml2::XMLNode* pXmlNode, const char * pcFieldName, const std::string & value, bool bIsCdata); int GenReturnXml(const std::string & sEncryptMsg, const std::string & sSignature, const std::string & sTimeStamp, const std::string & sNonce, std::string & sResult); }; }