In front of the

The user id of a small program can be exchanged by using the jSCOde2Session interface provided by wechat as mentioned above. The small program also provides a getUserInfo API to obtain user data. This user data can also contain the current user id OpenID. In this paper, how to obtain user data and data integrity check in the small program content to expand in detail

The API is introduced

Wx. getUserInfo is the API used to obtain user information. The following are the corresponding parameter fields:

field type If required
withCredentials Boolean no
lang String no
timeout Number no
success Function no
fail Function no
complete Function no

lang

Lang specifies the language in which user information is returned, with three values:

  • Zh_CN Simplified Chinese
  • Zh_TW Traditional Chinese
  • En The default value is EN

timeout

Timeout Specifies the timeout period for an API call. GetUserInfoAPI is actually an HTTP request initiated by the client to obtain user data, which is returned to the small program after encapsulation.

withCredentials

The withCredentials field is a Boolean value that determines whether the data returned by the applets when they call the API should contain the logon status information. Otherwise, the default value of this field is true

The API returns the following result:

field type describe
encryptedData String Encrypted user data
iv String Decryption algorithm vector
rawData String User open data
signature String The signature
userInfo Object User open data

If the value of this field is false, the above two fields: encryptedData, iv are not returned.

  • EncryptedData is the encryptedData of the complete user information, including sensitive data, such as the openid and unionid of the user. So the algorithm used for data encryption is AES-128-CBC block symmetric encryption and decryption algorithm, and then we analyze this encryption algorithm in detail.

  • Iv is the algorithm initial vector of the above decryption algorithm. Again, we’ll talk more about that later.

  • RawData is an object string that contains some open data about the user: NickName (wechat nickName), province(province), Language (wechat client language), Gender (user gender), country(country), city(city), avatarUrl(wechat profile picture address)

  • Signature To ensure the validity and security of the data, the applets sign the plaintext data. This value is the calculated value of rawData + session_key (SHA1), which is a password hash function that is more resistant to attacks than the MD5 hash function.

  • The userInfo field is an object and user open data, just as rawData presents it, except rawData serializes the object as a string as the return value.

API HTTP request

I told you before that when getUserInfoAPI is called in the client, the wechat client will send a request to the wechat server, which can be seen in the wechat developer tool through HTTP request packet capture. Issued a https://servicewechat.com/wxa-dev-logic/jsoperatewxdata HTTP requests.

The request body carries several important parameters, including data, grant_type, etc. The data field is a JSON string containing a field API_name with the value ‘webAPI_userinfo’. The grant_type field also corresponds to a value “webAPI_userinfo”.

The response body returns a JSON object, starting with a Baseresponse field containing the interface call return code errCode and the call result errMsg. The object also returns a data field, which corresponds to a JSON string containing all the user data obtained by calling the API. In the developer tool, we can also see that a debug_info field is returned, which also contains the user’s data, but the data here also returns the user’s OpenID, and also returns the user’s session_key login state credentials.

Generally, we can debug the validity of some information, including the user’s session_key and openID, by capturing packages in the developer tools.

Aes-128-cbc encryption algorithm

The aes-128-CBC algorithm is used to encrypt and decrypt the user’s complete data, which is obtained through the API. First let’s understand what AES-128-CBC is:

AES is an Encryption Standard for electronic data established by the National Institute of Standards and Technology (NIST) in 2001. It is a block Encryption Standard with a block size of 128 bits anda key length of 128, 192, and 256 bits.

There are five modes of packet encryption, respectively

ECB(Electronic Codebook Book) mode

Cipher Block Chaining (CBC) Indicates the Cipher Block Chaining mode

CTR(Counter) calculator mode

Cipher FeedBack (CFB) Indicates the Cipher FeedBack mode

OFB(Output FeedBack) Indicates the Output FeedBack mode

Here we mainly look at the packet encryption algorithm aes-128-CBC, which converts the plaintext and ciphertext using the same set of keys. 128bit is a group, 128bit is 16 bytes, so each 16-byte group of plaintext corresponds to the encrypted 16-byte ciphertext. If there is less than 16 bytes of plaintext left at the end, it needs to be filled, usually using PKCS#7(PKCS#5 only supports filling 8-byte blocks, while PKCS#7 supports filling 1-255 byte blocks).

If the last remaining plaintext is 13 bytes, that is, three bytes are missing to form a group, then three bytes of 0x03 need to be padded:

Plaintext data: 05 05 05 05 05 05 05 05 05 05 05 05 PKCS#7 fill: 05 05 05 05 05 05 05 05 05 05 05 05 05 05 03 03 03 03Copy the code

If the plaintext is exactly a multiple of 16 bytes, a group of 16 bytes 0x10 is added at last for encryption.

Therefore, we find two characteristics of PKCS#7 filling:

  • The filled bytes are all the same byte

  • The value of this byte is the number of bytes to be filled

We’ll watch plaintext encrypted process, CBC mode for each to be encrypted password piece before encryption before and a code block cipher is exclusive or operation, and then will get results through encryption device encryption, one of the first password will block the iv we mentioned with initialization vector exclusive or operation of the data block. The following image is from Wikipedia:

However, it should be clarified that the IV returned by the API is the initialization vector corresponding to the decryption algorithm, not the initialization vector corresponding to the encryption algorithm. As you can probably guess, the first cipher block in CBC mode decryption also requires xOR operation with the initialization vector. The following image is from Wikipedia:

In the applet, the encryption and decryption ciphers here are the Base64-encoded session_key obtained in our last article.

Application in applets

Nodejs decrypts user data on the server and verifies the integrity of the decrypted data. Nodejs decrypts user data on the server and verifies the integrity of the decrypted data.

In the util.js file, two methods are defined:

The decryptByAES method decrypts the encryptedData using the session_key that the server gets at login through the JSCOde2Session interface provided by wechat and the IV initialization vector that will be returned after calling wx.getUserInfo.

EncryptedBySha1 encrypts the session_key using the SHA1 hash algorithm to generate the user login identifier of the applets to ensure the security of the session_key.

// util.js
const crypto = require('crypto');
module.exports = {
    decryptByAES: function (encrypted, key, iv) {
        encrypted = new Buffer(encrypted, 'base64');
        key = new Buffer(key, 'base64');
        iv = new Buffer(iv, 'base64');
        const decipher = crypto.createDecipheriv('aes-128-cbc', key, iv)
        let decrypted = decipher.update(encrypted, 'base64'.'utf8')
        decrypted += decipher.final('utf8');
        return decrypted
    },
    encryptBySha1: function (data) {
        return crypto.createHash('sha1').update(data, 'utf8').digest('hex')}};Copy the code

In auth.js, we call the getSessionKey method from the previous article to obtain the openID and session_key of the user. After obtaining both, we decrypt the encrypted user data. At the same time, decrypted user data and user session_key and skey are stored in the data table.

One thing to note here: EncryptedData also returns a unionId field if the applet is currently bound to an open platform mobile or web application, or to a public platform public number, etc. This field differentiates the uniqueness of the user between the applet and other bound platforms. For different applications under the same wechat open platform, unionID is the same. Generally, we can use the unionId to get through the user login state between applets and other applications.

// auth.js
const { decryptByAES, encryptBySha1 } = require('.. /util');
return getSessionKey(code, appid, secret)
    .then(resData= > {
        // Select an encryption algorithm to generate your own logon state id
        const { session_key } = resData;
        const skey = encryptBySha1(session_key);

        let decryptedData = JSON.parse(decryptByAES(encryptedData, session_key, iv));
        // Store to user data table
        return saveUserInfo({
            userInfo: decryptedData,
            session_key,
            skey
        })
    })
    .catch(err= > {
        return {
            result: - 10003..errmsg: JSON.stringify(err)
        }
    })
Copy the code

Verify data integrity and validity

When we get the complete data of the user through decryption, we can verify the integrity and validity of the data to prevent the user data from being maliciously tampered. Here is how to verify the relevant data:

Validity check: When the withCredentials are set to true, the data returned will also have a signature field, which is the result of SHA1 (rawData + session_key). Use the same SHA1 algorithm to calculate the corresponding signature2 on its own server, that is

signature2 = encryptedBySha1(rawData + session_key);
Copy the code

Verify the integrity of user data by comparing signature and Signature2.

Integrity check: in front of encryptedData and related after decryption operation, will see the user data object is a watermark in the fields of official called watermark data, the field structure as follows:

"watermark": {
    "appid":"APPID"."timestamp":TIMESTAMP
}
Copy the code

Here, students can verify whether the appID in the watermark is consistent with their own APPID, and the timestamp of the data in the watermark to verify the timeliness of data.

The last

So the above is the small program how to encrypt and decrypt the user data operation, and how to the user data related processing and verification of the introduction, please give more advice!

Reference article:

Password algorithm – AES

AES five encryption modes (CBC, ECB, CTR, OCF, CFB)

Some understanding of the encryption algorithm AES-128-CBC

Advanced Encryption Standard AES working mode (ECB, CBC, CFB, OFB)


IVWEB Technology Weekly shocked online, pay attention to the public number: IVWEB community, weekly timing push quality articles.

  • Collection of weekly articles: weekly
  • Team open source project: Feflow