forked from BigBrotherTrade/flower
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathWXBizMsgCrypt.h
136 lines (107 loc) · 5.38 KB
/
WXBizMsgCrypt.h
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#pragma once
#include <string>
#include <cstdint>
#include "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 sReceiveId: 不同场景含义不同,详见文档
WXBizMsgCrypt(const std::string &sToken,
const std::string &sEncodingAESKey,
const std::string &sReceiveId)
:m_sToken(sToken), m_sEncodingAESKey(sEncodingAESKey),m_sReceiveId(sReceiveId)
{ }
//验证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_sReceiveId;
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);
};
}