You don’t even know the signature of the external interface? Study when you have time

Time:2021-7-28

background

Wednesday, 18:00.

Xiao Ming twisted his slightly sour neck, rubbed his eyes and stared at the screen.

Finally, the work was finished, and the whole people became relaxed near work.

“The docking party needs us to provide new services. It will go online next Tuesday. I’ll send you the demand. It’s very simple.”

A message from the barber broke the beautiful.

You don't even know the signature of the external interface? Study when you have time

“I can go to him. Every demand comes soon after work.” Xiao Ming could not help muttering, but he didn’t stop.

“OK, I’ll look at the demand first.”

After the reply, click the requirements document, which is really very simple.

Provide an interface for the external docking party to add a new merchant.

Keep consistent with the new merchants in the internal console.

It’s really not too difficult. Xiao Ming thinks about it. Although the new merchants in the internal console don’t do it themselves, the interface should be able to be reused directly, and the code should also be able to be reused.

But I haven’t done external docking before. I don’t know if there are other pits.

It will go online next Tuesday, so it is necessary to let the test mention and let the test intervene next Monday.

Xiao Ming opened the calendar. Today, Wednesday, there are only two days left for his interface document writing, detailed design, coding and self-test.

It should have been sufficient, but usually there will be all kinds of work chores to deal with, which will reduce the overall work efficiency.

Let’s first ask our colleagues for the previous code and documents.

Seeing that the time had passed the off-duty time, Xiao Ming sighed.

Interface documentation

Documentation

Thursday, 9:30.

Xiao Ming started to write interface documents when he came to the company. He has the basis of previous documents and writes very quickly.

However, the external interface is still somewhat different. Xiao Ming adds fields such as traceid and requesttime according to his own understanding to facilitate the troubleshooting and positioning of problems.

So the basic interface is written:

Request parameters:

Serial number parameter describe Required explain
1 traceId Unique identification yes Used to uniquely locate a request, a 32-bit string
2 requestTime Request parameters yes Request time, yyyymmddhhmmssss 17 bit timestamp
3 username user name yes Maximum 64 bit string
4 password password yes Up to 128 bit string, MD5 encrypted
5 address address no Maximum 128 bit string

Response parameters:

Serial number parameter describe Required explain
1 respCode Response coding yes 000000 indicates success. See response code enumeration for others
2 respDesc Response description yes Request time, yyyymmddhhmmssss 17 bit timestamp
3 userId User ID yes A 32-bit string that uniquely identifies the user after successful creation

Xiao Ming wrote down the request mode, precautions and corresponding enumeration values of the whole interface in detail.

And the basic detailed design documents are also sorted out.

1762 words, Xiao Ming looked at the total number of words and smiled bitterly.

This document is obviously not as concise as the requirements document.

As soon as I looked up, it was already 11:30, good guy. Time flies.

So I booked the meeting room at 14:00 p.m. to prepare the documents with the product manager, test and project manager.

Document review

Meeting room 14:00.

Xiao Ming came to the meeting room on time, plugged in the projector in advance and waited for everyone to come.

“The demand I raised yesterday is simple.”, The product manager came in smiling as soon as he got to the door.

“Yes, it’s OK.”

Then, the project manager and test came in together.

“Hurry through the requirements document,” said the project manager.

Xiao Ming cleared his throat and talked about the overall project background. And I went through my detailed design and interface documents.

At the end of the day, the product manager bowed his head and did other things. These details don’t need to be concerned.

The test listened carefully, kept asking their own questions, and later they need to verify themselves.

“Any other questions?”, Xiao Ming himself kept talking for more than half an hour and felt a little boring.

“I have no problem,” the test said. “What I care about most is when I can take the test?”

“Next Monday,” Xiaoming paused, “I guess I can’t start coding until after the meeting.”

“That’s OK,” the test replied, adding that he had no other questions.

“Your document is very detailed,” the project manager looked at Xiao Ming with a little approval, “but there is a problem. Your interface doesn’t even have a signature.”

“Signature, what signature?”, Xiao Ming is a little confused.

“You don’t even know the signature of the external interface? You still have to study when you have time. “, The project manager was clearly disappointed.

“Well, don’t say that.”, The product manager then joined the conversation, “is it OK for such a simple demand next Tuesday?”

“There should be no problem, as long as the test is carried out on time”, the test looked at Xiao Ming.

“There should be no problem,” said Xiao Ming, who was still thinking about the interface signature. “I’ll go back and look at the interface signature and adjust the interface.”

Interface signature

Signature function

Xiao Ming checked and found the external interface. Security must be considered.

In order to ensure the security of data and prevent information from being tampered with, signature is a common way.

You don't even know the signature of the external interface? Study when you have time

Signature implementation

There are many ways to implement, and the more common ways are:

(1) Sort all parameters, excluding the checkvalue itself, in ascending alphabetical order by parameter name.

(2) The sorted parameters are spliced into strings according to parameters and values

(3) Use the key agreed by both parties to MD5 encrypt the spliced string to obtain the checkvalue value

(4) Set the corresponding value to the checkvalue property

Of course, there may be differences in the implementation of signature, but both parties can keep consistent.

Signature verification

Knowing how to add a signature and verify is similar.

Repeat steps (1), (2) and (3) above to obtain the corresponding checkvalue.

Then compare it with the value passed by the other party. If it is consistent, it indicates that the signature verification has passed.

Interface adjustment

After understanding the necessity of signature, Xiao Ming added the property value of checkvalue in the interface document.

And had a private communication with the test. Here, the document is preliminarily completed.

Seeing that the time had passed the off-duty time, Xiao Ming sighed.

code implementation

V1 version

Friday, 10:00.

Xiao Ming started coding when he came to the company. After other things were handled almost, there was only the implementation of signature.

At the beginning, I didn’t think much about it, but directly realized the following:

/**
 *Manually build signature verification results
 *@ return result
 * @since 0.0.2
 */
public String buildCheckValue() {
    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.append(name);
    stringBuilder.append(password);
    //Other attributes
    return Md5Util.md5(stringBuilder.toString());
}

Of course, as a utilitarian, Xiao Ming is aware of a problem.

There must be similar tools in other projects. You should not make wheels again.

V2 version

A copy of the tool class is copied from other applications, and the implementation is as follows:

import com.github.houbb.heaven.util.lang.StringUtil;
import com.github.houbb.heaven.util.lang.reflect.ClassUtil;
import com.github.houbb.heaven.util.lang.reflect.ReflectFieldUtil;
import com.github.houbb.heaven.util.secrect.Md5Util;

import java.lang.reflect.Field;
import java.util.*;

/**
 * @author binbin.hou
 * @since 1.0.0
 */
public class CheckValueUtils {

    private CheckValueUtils(){}

    public static String buildCheckValue(Object object) {
        Class<?> clazz = object.getClass();

        //Get fieldMap for all fields
        Map<String, Field> fieldMap = ClassUtil.getAllFieldMap(clazz);

        //Remove name of checkvalue
        fieldMap.remove("checkValue");

        //Sort fields by name
        Set<String> fieldNameSet = fieldMap.keySet();
        List<String> fieldNameList = new ArrayList<>(fieldNameSet);
        Collections.sort(fieldNameList);

        //Reflection gets the value of all strings
        StringBuilder stringBuilder = new StringBuilder();
        for(String fieldName : fieldNameList) {
            Object value = ReflectFieldUtil.getValue(fieldName, object);
            //Reflection get value
            String valueStr = StringUtil.objectToString(value, "");

            //Splicing
            stringBuilder.append(fieldName).append("=").append(valueStr);
        }


        //MD5 signature
        return Md5Util.md5(stringBuilder.toString());
    }
}

Generally speaking, it’s easy to use, and I don’t have much time. Just use it directly.

After all, the self-test work is completed. After stepping on the pit once, Xiaoming passed the self-test of the whole interface.

“In this way, it’s time to test.”

Seeing that the time had passed the off-duty time, Xiao Ming sighed.

You don't even know the signature of the external interface? Study when you have time

More elegant signature implementation

Generally speaking, the story ends here.

However, Xiao Ming’s idea kept the story going.

Insufficient tools and methods

The original method can basically meet most of the needs, but it will become more troublesome to make adjustments.

For example, some very large fields do not participate in countersigning, and the name of the countersigning field is not called checkvalue, but changed tosign, adjust the field sorting method, etc.

These will make the original tools and methods unavailable and need to be copied and modified again.

Can we implement a more flexible signing tool?

The answer is yes. Xiao Ming spent two days on the weekend to implement a signing tool.

Quick start

Maven introduction

<plugin>
    <groupId>com.github.houbb</groupId>
    <artifactId>checksum</artifactId>
    <version>0.0.6</version>
</plugin>

POJO object

  • User.java
public class User {

    @CheckField
    private String name;

    private String password;

    @CheckField(required = false)
    private String address;

    @CheckValue
    private String checksum;

    //Getter & Setter
    //toString()
}

Two core notes are involved:

@CheckFieldIndicates the field information involved in signing. By default, all fields are involved in signing. appointrequired=falseSkip tagging.

@CheckValueIndicates the field where the signature result is stored. The field type needs to be string type.

Later, a string and different types of conversion implementations will be added to expand the application scenario.

Get signature

See for all tool class methodsChecksumHelper, and the following methods support specifying secret keys.

User user = User.buildUser();

final String checksum = ChecksumHelper.checkValue(user);

This method will specify the user in the user object@CheckFieldAll fields are processed,

By specifying the sorting and splicing, and then combined with the specified encryption strategy to build the final signature verification result.

Fill signature

User user = User.buildUser();

ChecksumHelper.fill(user);

The corresponding checkvalue value can be filled in by default@CheckValueOn the specified field.

Verify signature

User user = User.buildUser();

boolean isValid = ChecksumHelper.isValid(user);

The current user object will be signed, and the signed result will be compared with the user’s own signature.

Boot class

Checksumbs boot class

In order to meet more flexible scenarios, we introduce the checkpoint BS boot class based on fluent API.

The above configuration is equivalent to:

final String checksum = ChecksumBs
        .newInstance()
        .target(user)
        .charset("UTF-8")
        .checkSum(new DefaultChecksum())
        .sort(Sorts.quick())
        .hash(Hashes.md5())
        .times(1)
        .salt(null)
        .checkFieldListCache(new CheckFieldListCache())
        .checkValueCache(new CheckValueCache())
        .checkValue();

Configuration description

All the above configurations can be flexibly replaced, and all implementations support user customization.

attribute explain
target Object to be signed
charset code
checkSum Specific signature implementation
sort Field sorting strategy
hash String encryption hash policy
salt Encrypt the corresponding salt value
times Number of encryption
checkFieldListCache Cache implementation of fields to be signed
checkValueCache Cache implementation of signature field

performance

background

Every time we talk about reflection, the first reaction is convenience, and the second reaction is performance.

Sometimes you choose to manually copy and paste again and again because you care about performance.

performance

See for detailsBenchmarkTest.java

You don't even know the signature of the external interface? Study when you have time

100W tests and verifications are conducted this time, and the time consumption is as follows.

Manual processing time: 2505ms

Annotation processing time: 2927ms

Summary

Signature in the communication of external interface can ensure that the information is not tampered with.

I hope this tool can help you get off work on time.

I’m old ma. I look forward to seeing you again next time.

Recommended Today

Implementation example of go operation etcd

etcdIt is an open-source, distributed key value pair data storage system, which provides shared configuration, service registration and discovery. This paper mainly introduces the installation and use of etcd. Etcdetcd introduction etcdIt is an open source and highly available distributed key value storage system developed with go language, which can be used to configure sharing […]