FXSend/WxWork/WXBizMsgCrypt.h
2025-02-28 17:05:50 +08:00

137 lines
5.1 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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);
};
}