Web authentication and API using token

Time:2020-10-29

First of all, I’ll post the article I’ve read:
1.http://www.cnblogs.com/xiekel…
2.http://blog.leapoahead.com/20…
3.http://blog.leapoahead.com/20…
4.jwt demo :https://github.com/bigmeow/JWT
Five https://github.com/jwtk/jjwt There are several good ones here, which are officially recommended
Six http://blog.csdn.net/koastal/… Anti replay attack scheme based on timestamp and nonce

The company’s current web design is based on HTTP basic auth, and has always felt that there will be great security problems, and replay attacks are very simple to implement.

To quote a paragraph from the first article: http basic auth simply states that every time an API is requested, the user’s username and password are provided. In short, basic auth is compatible with restful API The simplest way of authentication is to provide the user name and password. However, due to the risk of exposing the user name and password to the third-party client, it is used less and less in the production environment. Therefore, HTTP basic auth should be avoided when developing restful API.

Feel that the way to use token to achieve web and API authentication. JSON web token is a relatively mature solution, so we adopt JSON web token. For a basic introduction to JSON web token, please refer to the following three connections at the beginning of the article.

JWT solves:
1. As token authentication, it solves the problem of user directly entering account number and password for authentication.
2. Some data security transmission problems (for example, the article of the second link is to add attention, and the connection generated by the server can be sent to the target customer safely by mail without exposing the relevant information of the operating user).

As a token, JWT’s payload needs to have a user information field. Otherwise, how to know which user is operating? Generally, do not fill in sensitive information, such as user password, because it is encoded by Base64 and can be cracked. The interface for users to log in and get token needs to be encrypted by HTTPS, otherwise the user account and password will be exposed, and there will be no security to speak of.

When requesting, token can be uploaded in the following ways:
1. Through cookie
2. Through the HTTP authorization head
3. Get / post method, directly in the form of parameters.

Security:
1. Firstly, it is necessary to ensure that the interface between login and token needs to be encrypted by HTTPS
2. Prevent replay attack: at present, there is a shared secret key between the client and the server. When calling the API, the method, parameter and token of the API need to be signed once (JWT is available). The server first verifies whether the signature of method, parameter and token is correct, and then verifies whether the signature of token is correct. The first signature ensures that even if the request is hijacked, the hijacker has no way to fake other requests or modify parameters, which ensures the security to a certain extent. The second signature verification is mainly to verify the validity of token and verify the user’s identity.

The above steps need to save two kinds of secret keys on the server. The first is the secret key of the production token, which is only known by the server program. The second secret key is a shared secret key for each developer who uses the interface. This secret key only needs to be known by the server and the developer (developers can log in to the website and customize their own shared secret key when applying for the interface).

3. Storage of shared secret key: the shared secret key needs to be kept safely and can not be disclosed.

———————–The following copy is from link 6——————————————
In the past, timestamp is always used to prevent replay attacks, but this does not guarantee that every request is one-time. Today, I saw an article about how to use nonce (number used once) to ensure one-time effectiveness. I feel that a combination of the two can achieve a very good effect.

Replay attack is one of the common attack methods of hackers in the computer world. The so-called replay attack is that the attacker sends a packet that has been received by the target host to cheat the system, which is mainly used in the process of identity authentication.
First of all, we should make it clear that replay attack is a secondary request. The hacker obtains the requested HTTP message through packet capture, and then the hacker writes a similar HTTP request and sends it to the server. That is to say, the server processes two requests, first the normal HTTP request, and then the tampered HTTP request sent by hacker.

Scheme based on Timestamp

Each HTTP request needs to add the timestamp parameter, and then digitally sign the timestamp together with other parameters. Since a normal HTTP request usually does not exceed 60s from the time it is sent to the server, after receiving the HTTP request, the server first judges whether the timestamp parameter is more than 60s compared with the current time. If it exceeds 60s, it is considered as an illegal request.

If the hacker gets our request URL through packet capture:
http://koastal.site/index/Inf…
among

$sign=md5($uid.$token.$stime);
//The server can read the token from the database through uid

In general, it takes more than 60s for hackers to replay the request from packet capture, so the time parameter in the request is invalid.
If the hacker changes the time parameter to the current time stamp, the digital signature corresponding to the sign parameter will be invalid, because the hacker does not know the token value and has no way to generate a new digital signature.

However, the vulnerability of this method is also obvious. If the replay attack is carried out within 60 seconds, there is no way. Therefore, this method can not guarantee that the request is valid only once.

Scheme based on nonce

Nonce means a valid random string only once. Each time a request is made, the parameter must be different. Therefore, this parameter is generally related to the timestamp. For convenience, we directly use the hexadecimal of the timestamp. In actual use, we can add the client’s IP address, MAC address and other information to make a hash, which is used as the nonce parameter.
We store the nonce parameters of each request in a “collection”, which can be stored in the database or cache in JSON format.
When processing an HTTP request, first judge whether the nonce parameter of the request is in the “collection”. If it exists, it is considered as an illegal request.

If the hacker gets our request URL through packet capture:
http://koastal.site/index/Inf…

among

$sign=md5($uid.$token.$nonce);
//The server can read the token from the database through uid

When the nonce parameter is first requested, it has been stored in the “collection” on the server. If the request is sent again, it will be recognized and rejected.
As a part of the digital signature, the nonce parameter cannot be tampered with, because hackers do not know the token, so they can not generate a new sign.

There is also a big problem with this method, that is, the “set” storing nonce parameters will become larger and larger, and the time consuming to verify whether the nonce exists in the “set” will be longer and longer. We can’t make the nonce “set” infinite, so we need to clean up the “set” regularly, but once the “set” is cleaned up, we can’t verify the cleaned nonce parameters. In other words, assuming that the “collection” is cleaned up once a day on average, we can still replay the URL every other day, although we can’t replay the URL at that time. Moreover, storing the “nonce” parameters of all requests within 24 hours is also a big expense.

Scheme based on timestamp and nonce

What if we use both timestamp and nonce parameters?
One time nonce can solve the problem of 60s of timestamp parameter, and timestamp can solve the problem of increasing “set” of nonce parameters.

Based on the timestamp scheme, we add the nonce parameter. Because the timstamp parameter is considered illegal for requests over 60s, we only need to store the “collection” of the nonce parameters for 60s.

If the hacker gets our request URL through packet capture:
http://koastal.site/index/Inf…

among

$sign=md5($uid.$token.$stime.$nonce);
//The server can read the token from the database through uid

If the HTTP request is replayed within 60 seconds, because the nonce parameter has been recorded in the server’s nonce parameter “collection” at the time of the first request, it will be judged as an illegal request. After 60 seconds, the still parameter will be invalid. At this time, because the hacker does not know the value of the token, he cannot regenerate the signature.

To sum up, we think that a normal HTTP request will not be sent for more than 60 seconds. The replay attack within 60 seconds can be guaranteed by the nonce parameter, and the replay attack over 60 seconds can be guaranteed by the still parameter.

Because the nonce parameter only works within 60s, it is only necessary to save the nonce parameter within 60s.

We don’t have to clean the set of nonce parameters every 60s. We just need to judge the last modification time of the nonce set when a new nonce arrives. If it exceeds 60s, clear the set and store the new nonce parameter set. In fact, the nonce parameter set can be stored for a longer time, but it is at least 60s.

Validation process

//Determine whether the still parameter is valid
if( $now – $stime > 60){

Die ("request timeout");

}
//Determine whether the nonce parameter already exists in the set
if( in_array($nonce,$nonceArray) ){

Die ("request only valid once");

}
//Verify digital signature
if ( $sign != md5($uid.$token.$stime.$nonce) ){

Die ("digital signature verification failed");

}
//Determine whether the nonce collection needs to be cleaned up
if( $now – $nonceArray->lastModifyTime > 60 ){

$nonceArray = null;

}
//Record the nonce parameter of this request
$nonceArray.push($nonce);

//Start processing legitimate requests