# Overview
When third-party platform developers receive and process messages on behalf of authorized Official Accounts, the message content must be encrypted and decrypted for security.
This document uses sample code to show how to perform encryption and decryption. By referencing this document and using the sample code, you will find that it is easy to implement these features. For a more detailed explanation, you can refer to the Technical Solution for Encryption/Decryption by Official Accounts Third-Party Platforms.
Note that developers need to encrypt and decrypt messages and events they received (some events require replies, in which case the reply must be encrypted before being sent). However, when they send messages by calling an API (such as the "Customer Service Messaging" API), encryption is not necessary.
Developers can use the Weixin Official Accounts Platform API Debugging Tool to perform online message encryption/decryption debugging. Select Message API Debugging for API Type and Security Mode for Encryption Debugging.
# Message Type
Third-party platforms can receive two types of messages:
Messages sent by users to Official Accounts/Mini Programs (and received by the third-party platform on their behalf). In the XML body of these messages, the ToUserName (i.e., the recipient) is the original ID (obtained via the "Get Authorizer's Basic Account Information" API) of the Official Accounts/Mini Programs.
Notifications or events pushed by the Weixin server to the third-party platform (such as authorization cancellation notifications or component_verify_ticket pushing). In the XML body of these messages, the ToUserName field is replaced by the AppID field which is the AppID of the third-party platform. After you receive these system event push notifications, you must decrypt them and simply return the string
success
.
Specific process for message encryption/decryption: When followers interact with authorized Official Accounts, the third-party platform receives the relevant message and event notifications. The Weixin server takes two measures to enhance the security of this process:
In the URL used to receive messages and events from authorized Official Accounts, two parameters are added (in addition to the two exiting parameters timestamp and nonce): encrypt_type (the encryption type, set to aes) and msg_signature (the message signature, used to verify the accuracy of the message body).
The XML body in postdata is encrypted using the message encryption symmetric_key (also called EncodingAESKey) obtained when you applying for the third-party platform.
# Sample Code
The Weixin Official Accounts Platform provides code samples in five languages: C++, PHP, Java, Python, and C# 5. Click here to download the sample code and be sure to read the Readme file before running the code. The class names and API names are the same for each language. In what follows, we use C++ as an example.
1. Function Description
1.1 Constructor Function
// @param sToken: The token used to verify received messages, which is entered when you apply for a third-party platform.
// @param sEncodingAESKey: The symmetric_key used to encrypt received messages, which is entered when you apply for a third-party platform.
// @param sAppid: The Official Accounts third-party platform's appidWXBizMsgCrypt(const std::string &sToken,
const std::string &sEncodingAESKey,
const std::string &sAppid)
1.2 Decryption Function
// This function verifies the authenticity of the message and gets the decrypted plaintext.
// @param sMsgSignature: The signature string, corresponding to the msg_signature in the URL parameter.
// @param sTimeStamp: The timestamp, corresponding to timestamp in the URL parameter.
// @param sNonce: A random string, corresponding to the nonce in the URL parameter.
// @param sPostData: The ciphertext, corresponding to the data in the POST request.
// @param sMsg: The decrypted plaintext, valid when the return value is 0.
// @return: This value is 0 when the request is successful and the error code if the request failed.
int DecryptMsg(const std::string &sMsgSignature,
const std::string &sTimeStamp,
const std::string &sNonce,
const std::string &sPostData,
std::string &sMsg);
1.3 Encryption Function
//This function encrypts and packages messages sent in reply to the Official Account user.
// @param sReplyMsg:The message to be sent to the Official Account user as a string in xml format.
// @param sTimeStamp: The timestamp. You can generate one or use the timestamp in the URL parameter.
// @param sNonce: A random string. You can generate one or use the nonce in the URL parameter.
// @param sEncryptMsg: The ciphertext of the encrypted message, which can be directly sent to the user. It is a string containing the msg_signature, timestamp, nonce, and encrypt values in XML format. When the return value is 0, the request is successful.
// return: This value is 0 when the request is successful and the error code if the request failed.
int EncryptMsg(const std::string &sReplyMsg,
const std::string &sTimeStamp,
const std::string &sNonce,
std::string &sEncryptMsg);
2. How to Use
2.1 Instantiate an Object
Use the constructor to instantiate an object and provide the third-party platform's token (the token used to verify received messages, which is entered when you apply for a third-party platform), the third-party platform's AppID, and the third-party platform's EncodingAESKey (the symmetric_key used to encrypt received messages, which is entered when you apply for a third-party platform).
2.2 Decrypt the Message
In security mode, the third-party platform receives the following message body that contains ciphertext:
encrypt_msg =
<xml>
<ToUserName></ToUserName>
<Encrypt></Encrypt>
</xml>
Call the DecryptMsg function in the sample code (parameters msg_signature, timetamp, nonce, and postdata must be passed; the first three can be obtained from the URL used to receive messages and events from authorized Official Accounts, and postdata is the data content of the POST request). If the call is successful, sMsg is the output result and its content is the XML message body in plaintext:
<xml>
<ToUserName></ToUserName>
<FromUserName></FromUserName>
<CreateTime>1411035097</CreateTime>
<MsgType></MsgType>
<Content></Content>
<MsgId>6060349595123187712</MsgId>
</xml>
2.3 When Official Accounts process messages, they generate the XML message body of the reply and send it to the Weixin Official Accounts Platform. Let's assume the content of the reply is as follows:
res_msg =
<xml>
<ToUserName></ToUserName>
<FromUserName></FromUserName>
<CreateTime>1411034505</CreateTime>
<MsgType></MsgType>
<Content></Content>
<FuncFlag>0</FuncFlag>
</xml>
2.4 Encrypt the Response Package
Call the EncryptMsg API and pass the res_msg, timestamp and nonce of the reply to the Weixin Official Accounts Platform. If encryption is successful, sEncryptMsg is the message body in ciphertext, as shown below:
<xml>
<Encrypt>
<![CDATA[LDFAmKFr7U/RMmwRbsR676wjym90byw7+hhh226e8bu6KVYy00HheIsVER4eMgz/VBtofSaeXXQBz6fVdkN2CzBUaTtjJeTCXEIDfTBNxpw/QRLGLq
qMZHA3I+JiBxrrSzd2yXuXst7TdkVgY4lZEHQcWk85x1niT79XLaWQog+OnBV31eZbXGPPv8dZciKqGo0meTYi+fkMEJdyS8OE7NjO79vpIyIw7hMBtEXPBK/tJGN5m5SoAS
6I4rRZ8Zl8umKxXqgr7N8ZOs6DB9tokpvSl9wT9T3E62rufaKP5EL1imJUd1pngxy09EP24O8Th4bCrdUcZpJio2l11vE6bWK2s5WrLuO0cKY2GP2unQ4fDxh0L4ePmNOVFJ
wp9Hyvd0BAsleXA4jWeOMw5nH3Vn49/Q/ZAQ2HN3dB0bMA+6KJYLvIzTz/Iz6vEjk8ZkK+AbhW5eldnyRDXP/OWfZH2P3WQZUwc/G/LGmS3ekqMwQThhS2Eg5t4yHv0mAIei
07Lknip8nnwgEeF4R9hOGutE9ETsGG4CP1LHTQ4fgYchOMfB3wANOjIt9xendbhHbu51Z4OKnA0F+MlgZomiqweT1v/+LUxcsFAZ1J+Vtt0FQXElDKg+YyQnRCiLl3I+GJ/c
xSj86XwClZC3NNhAkVU11SvxcXEYh9smckV/qRP2Acsvdls0UqZVWnPtzgx8hc8QBZaeH+JeiaPQD88frNvA==]]> </Encrypt>
<MsgSignature></MsgSignature>
<TimeStamp>1411034505</TimeStamp>
<Nonce></Nonce>
</xml>
3. Notes
The length of the EncodingAESKey is always 43 characters comprised of letters (a-z and A-Z) and numbers (0-9).
For security reasons, the Open Platform website provides an EncodingAESKey modification feature to modify the EncodingAESKey if it is disclosed. Therefore, we recommend that Official Accounts save the current and previous EncodingAESKey. If the decryption using the current EncodingAESKey fails, you should use the previous one. The key used to encrypt the response package is the one that can decrypt the message.