Detailed explanation of Taobao H5 sign encryption algorithm

Time:2020-10-8

Taobao uses a different way to access H5 from the client. Due to the high risk of saving appsercret in the JS code of H5, MTop adopts the method of randomly assigning token, which allocates a token for each access end, saves it in the user’s cookie, and brings back the token assigned by the server through the cookie, The client uses the assigned token to generate a digest value sign for the URL parameter of the request. MTop uses the extracted value and the token in the cookie to prevent URL tampering.

technological process

When the token in the local cookie is empty (usually the first visit), MTop will receive “fail”_ SYS_ TOKEN_ “Expired:: token expired” is an error response. At the same time, MTop will generate a token and write it to the cookie( response.cookies );
In the second request, JS generates a sign according to the agreed algorithm by reading the token value in the cookie. The sign is carried in the request of MTop. MTop calculates the sign in the same way as the token through the cookie and the token, and compares it with the requested sign. After checking the response returned to the API, the failure prompts “fail”_ SYS_ ILLEGAL_ Access:: illegal request “;

The token in the cookie is time sensitive. When the token fails, it will receive the response “fail”_ SYS_ TOKEN_ “Expired:: token expired”, and a new token will be written at the same time. JS will use the new token to recalculate the sign and resend the request;
As for the self checking of the token in the cookie, since the token is plaintext in the cookie, it may be counterfeited. The output cookie contains a token encrypted with the public key of asymmetric key. MTop will check whether the token in the cookie is allocated by the server (restore the token by using the encrypted token and private key, compared with the plaintext token returned)

Sign generation

On the generating formula of sign:


md5Hex(token&t&appKey&data)

For example: md5hex (“30dc68e5b4cf40ebd02fb05673c7e3b7 & 15722522062317 & 12345678 – {” itemnumid “:” 1502111132496 “}”)

sign=4c1e7b6853fa7a5e1b8f7066ee22932f

Implementation code:


public static String calcSignature(String token, String timestamp, String appKey, String data) {
        return DigestUtils.md5Hex(StringUtils.trimToEmpty(token) + "&"
                + timestamp + "&" + appKey + "&" + data);
    }

    public static void main(String[] args) {
        String token="30dc68e5b4cf40ebd02fb05673c7e3b7";
        String timestamp="1572522062317";
        String sign = calcSignature(token, timestamp, "12345678", "{\"itemNumId\":\"1502111132496\"}");
        System.out.println(sign);
    }

token

M_ H5tk: the format is plaintext token_ ExpireTime, from response.cookies For example: 30dc68e5b4cf40ebd02fb05673c7e3b7_ one trillion and five hundred and seventy-two billion five hundred and twenty-two million sixty-two thousand three hundred and seventeen

The token is 30dc68e5b4cf40ebd02fb05673c7e3b7
The failure time is 1572522062317

It can be encapsulated in a class to store token


@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Credentials implements Comparable<Credentials> {
    private String _m_h5_tk;
    private String _m_h5_tk_enc;

    private static final int OFFSET = 60000;

    public String getToken() {
        return StringUtils.isEmpty(_m_h5_tk) ? null : _m_h5_tk.substring(0, _m_h5_tk.indexOf("_"));
    }

    public long getExpireTimestamp() {
        long t = new Date().getTime() - OFFSET;
        if (StringUtils.isEmpty(_m_h5_tk) || StringUtils.isEmpty(_m_h5_tk_enc)) {
            return t;
        }
        try {
            return Long.parseLong(_m_h5_tk.substring(_m_h5_tk.indexOf("_") + 1));
        } catch (NumberFormatException e) {
            return t;
        }
    }

    public boolean isExpired() {
        if (StringUtils.isEmpty(_m_h5_tk) || StringUtils.isEmpty(_m_h5_tk_enc)) {
            return true;
        }
        return new Date().getTime() > getExpireTimestamp();
    }

    @Override
    public int compareTo(Credentials o) {
        return Long.compare(o.getExpireTimestamp(), this.getExpireTimestamp());
    }
}

t
Very simple, that is, the timestamp is obtained through new date(). Gettime()

appKey
The fixed value can be obtained in the request parameter through the packet capturing tool, and the parameter name is appkey

data
The submitted parameters can be obtained from the request parameters by the packet capturing tool, which is usually a JSON string

This article on the detailed explanation of Taobao H5 sign encryption algorithm is introduced here, more relevant Taobao H5 sign encryption content please search the previous articles of developeppaer or continue to browse the relevant articles below, I hope you will support developeppaer more in the future!