Technical Solution
Back

From WeChat Official Account Admin Platform
Jump to: navigation, search

Instructions

1. EncodingAESKey is 43-characters long (valid characters: a-z, A-Z, and 0-9). Developers can change this parameter in the server configuration section of the Developer Center on the WeChat Official Account Admin Platform.

2. AESKey: AESKey=Base64_Decode (EncodingAESKey + "="); it is 32-byte long and generated based on Base64_Decode by adding a "=" at the end of EncodingAESKey.

3. AES encryption is implemented in CBC mode. The key is 32-byte long and data is filled using PKCS#7; PKCS#7: K indicates number of bytes (32 bytes) in the key; buf indicates data to be encrypted and N indicates number of bytes of the data. Buf must be a multiple of K. Add (K-N%K) bytes at the end of buf and each byte contains (K- N%K) content.

Added Content
01 if ( N%K==(K-1))
0202 if ( N%K==(K-2))
030303 if ( N%K==(K-3))
... ...
KK....KK (K bytes) if ( N%K==0)

For details, please see http://tools.ietf.org/html/rfc2315.

4. For safety reasons, the WeChat Official Account Admin Platform allows developers to change EncodingAESKey if it becomes insecure. It is recommended that official accounts save the current and prior EncodingAESKey so that the prior key can be used if decryption based on the current key fails. When replying, the AESKey used for encryption must be identical to the one used for decryption.

5. In compatibility mode, a the message falls will be provided as into both plaintext and cyphertext, so the message length will be increased by two times approximatelynearly doubled. Developers should check their system to avoid receiving generating errors caused by overly long messages or excessive URL parameters.

6. The WeChat team provides code samples in PHP, it is recommended to use these samples.

In the following example, a text message is used to describe how the WeChat Official Account Admin Platform encrypts/decrypts messages. Common messages and event messages can be encrypted/decrypted using a similar method.

Developer Backend System Receives Message

Message Encryption

Currently, the message is a plaintext message using the following format:

msg = 
<xml>
	<ToUserName><![CDATA[toUser]]></ToUserName>
	<FromUserName><![CDATA[fromUser]]></FromUserName> 
	<CreateTime>1348831860</CreateTime>
	<MsgType><![CDATA[text]]></MsgType>
	<Content><![CDATA[this is a test]]></Content>
	<MsgId>1234567890123456</MsgId>
</xml>

In compatibility mode, the message isprovided as both plaintext and encrypted text using the following format:

new_msg=
<xml>
	<ToUserName><![CDATA[toUser]]></ToUserName>
	<FromUserName><![CDATA[fromUser]]></FromUserName> 
	<CreateTime>1348831860</CreateTime>
	<MsgType><![CDATA[text]]></MsgType>
	<Content><![CDATA[this is a test]]></Content>
	<MsgId>1234567890123456</MsgId>
	<Encrypt><![CDATA[msg_encrypt]]</Encrypt>
</xml>

In security mode, the message is encrypted using the following format:

new_msg=
<xml> 
	<ToUserName><![CDATA[toUser]]</ToUserName>
       <Encrypt><![CDATA[msg_encrypt]]</Encrypt>
</xml>

Where, msg_encrypt = Base64_Encode( AES_Encrypt[ random(16B) + msg_len(4B) + msg + $AppId])

The AES buf is composed of a 16-byte random character string, msg, 4-byte msg_len (network byte sequence), and $AppId; where msg_len indicates length of the msg and $AppId indicates the APP ID of the official account.

AESKey =Base64_Decode(EncodingAESKey + "="), 32 bytes

A new parameter encrypt_type appears on the URL. If encrypt_type does not exist or its value is raw, no encryption is implemented; if its value is aes, AES algorithm is used (currently only supports these two values).

Message Signature

In order to guarantee message validity, message signature is added on the WeChat Official Account Admin Platform for developers to authenticate message validity and decrypt those passing authentication.

A new parameter msg_signature appears on the URL.

msg_signature=sha1(sort(Token, timestamp, nonce, msg_encrypt))

Parameter Description
Token Token set by the developer on the WeChat Official Account Admin Platform
timestamp Time stamp, an original parameter on the URL
nonce Random number, an original parameter on the URL
msg_encrypt Encrypted message previously described

Message Authentication and Decryption

Developers should authenticate the message signature first. The message can be decrypted only if the authentication succeeds.

Authentication Method

1. Calculate the signature dev_msg_signature=sha1(sort(Token, timestamp, nonce, msg_encrypt))

2. Compare the dev_msg_signature with the msg_signature on the URL. If they are identical, authentication is successful.

Decryption Method

1. aes_msg=Base64_Decode(msg_encrypt)

2. rand_msg=AES_Decrypt(aes_msg)

3. Verify whether the $AppId is consistent with its own APP ID. If yes, the message is valid. This step further guarantees message validity.

4. Remove rand_msg (16-byte), msg_len (4-byte), and $AppId. The remaining is the XML message content.

Developer Backend System Replies

If the URL does not contain encrypt_type or its value is raw, a plaintext message is replied; otherwise, use the algorithm mentioned above to encrypt a reply message. In compatibility mode, official accounts can select to reply a plaintext message or an encrypted message (only choose one).

Signature and Encryption of Reply Message

Currently, the message uses the following format:

msg=
<xml>
	 <ToUserName><![CDATA[toUser]]></ToUserName>
	 <FromUserName><![CDATA[fromUser]]></FromUserName>
	 <CreateTime>12345678</CreateTime>
	 <MsgType><![CDATA[text]]></MsgType>
	 <Content><![CDATA[你好]]></Content>
</xml>

After encryption, the message format is as follows:

new_msg=
<xml>
	<Encrypt><![CDATA[msg_encrypt]]></Encrypt>
	<MsgSignature><![CDATA[msg_signature]]></MsgSignature>
	<TimeStamp>timestamp</TimeStamp>
	<Nonce><![CDATA[nonce]]></Nonce>
</xml> 

Where, msg_encrypt=Base64_Encode(AES_Encrypt [random(16B)+ msg_len(4B) + msg + $AppId])

random(16B) is a 16-byte random character string; msg_len indicates length of the msg and it occupies 4 bytes (network byte sequence); $AppId indicates the APP ID of the official account.

AESKey =Base64_Decode(EncodingAESKey + "="), 32 bytes

msg_signature=sha1(sort(Token, timestamp, nonce, msg_encrypt))

timestamp and nonce can be set to original values or regenerated ones.

Developer Guide
Custom-defined Menu
WeChat JS-SDK