It has always been timestamp to prevent replay attacks, but this does not guarantee that each request is one-time. Today I saw an article introduced by nonce (number used once) to ensure an effective, feel the combination of both, you can achieve a very good effect.
Replay attack is one of the most common ways for hackers in computer world, so the so-called replay attack is to send a packet that the host has received, in order to achieve the purpose of deception system, mainly for the identity authentication process.
The first thing to be clear, replay attack is two requests, the hacker grabbed the packet to obtain the requested HTTP message, and then the hacker himself wrote a similar HTTP request, sent to the server. In other words, the server processed two requests, processed the normal HTTP request, and then processed the tampered HTTP request sent by the hacker. based on the timestamp scheme
Each HTTP request requires the timestamp parameter to be added, and the timestamp is digitally signed with the other parameters. Because a normal HTTP request, from the issue to the server generally will not exceed 60s, so the server received the HTTP request, the first time to determine the timestamp parameters compared to the current time, whether more than 60s, if more than is considered illegal request.
If the hacker gets our request URL by grabbing the packet:
http://koastal.site/index/Info?uid=ZX07&stime=1480862753&sign=80b886d71449cb33355d017893720666
which
$sign =md5 ($uid. $token. $stime);
The server can read the token from the database by UID
In general, the hacker replay request from the capture time is far more than 60s, so the request in the Stime parameter has been invalidated.
If the hacker modifies the stime parameter to the current timestamp, the digital signature corresponding to the sign parameter is invalidated because the hacker does not know the token value and cannot generate a new digital signature.
However, the vulnerability in this way is also obvious, if the replay attack within 60s, there is no way, so this way does not guarantee that the request only once valid. based on the nonce scheme
Nonce means only a single valid random string, require each request, this parameter to ensure different, so this parameter is generally related to time stamps, we here for convenience, the direct use of the timestamp of the 16, the actual use can be added to the client's IP address, MAC address and other information to make a hash, As the nonce parameter.
We store each requested nonce parameter in a "collection" that can be stored in JSON format in the database or cache.
Each time an HTTP request is processed, the nonce parameter of the request is first judged whether it is in the collection, and if it exists, it is considered an illegal request.
If the hacker gets our request URL by grabbing the packet:
http://koastal.site/index/Info?uid=ZX07&nonce=58442c21&sign=80b886d71449cb33355d017893720666
which
$sign =md5 ($uid. $token. $nonce);
The server can read the token from the database by UID
When the nonce parameter is first requested, it is stored in the "collection" on the server, and the resend request is recognized and rejected.
The nonce parameter, as part of the digital signature, cannot be tampered with because the hacker is not clear about the token, so the new sign cannot be generated.
The big problem with this approach is that the "set" of stored nonce parameters gets bigger and longer, and it takes more time to verify that the nonce exists in the "collection." We cannot allow the Nonce "collection" to be infinite, so we need to periodically clean up the "collection", but once the "set" is cleaned, we cannot verify the nonce parameters that have been cleaned up. That is, assuming that the "set" is cleaned up on an average of 1 days, the URL we crawled to, although replay attacks were not possible at the time, we can replay attacks every other day. and storage within 24 hours, all the requested "nonce" parameters, but also a small amount of overhead. solutions based on timestamp and nonce
What if we use both timestamp and nonce parameters at the same time?
Nonce can solve the problem of timestamp parameter 60s, timestamp can solve the problem that the nonce parameter "set" is more and more big.
We add the nonce parameter on the basis of the timestamp scheme, because the Timstamp parameters are considered illegal requests for more than 60s requests, so we only need to store "set" of 60s nonce parameters.
If the hacker gets our request URL by grabbing the packet:
http://koastal.site/index/Info?uid=ZX07&stime=1480862753&nonce=58442c21&sign= 80b886d71449cb33355d017893720666
which
$sign =md5 ($uid. $token. $stime. $nonce);
The server can read the token from the database by UID
If the HTTP request is replayed within 60s, because the nonce parameter has been recorded in the server's nonce parameter "collection" at the time of the first request, it is judged to be an illegal request. After 60s, the stime parameter is invalidated, and the signature cannot be regenerated because the hacker is not aware of the value of the token.
In summary, we believe that a normal HTTP request sent no more than 60s, replay attacks within 60s can be guaranteed by the nonce parameters, more than 60s replay attacks can be guaranteed by the stime parameters.
Because the nonce parameter only works within 60s, you need to save only the nonce parameters within 60s.
We do not necessarily need each 60s to clean up the set of nonce parameters, just to determine when the new nonce arrives, to judge the last time the nonce set has been modified, over 60s, to empty the collection and store a new set of nonce parameters. In fact, the nonce parameter set can be stored longer, but at least 60s.
Random number set can be based on the business scene of a regular cleaning or automatic cleaning of the scheme, such as the interface for the maximum number of requests per second of 1000, then the maximum number of requests in 60s is 1500*60=90000, we check the collection size after each request is more than 90000, If ultra high the quantity is emptied.
Verification process
Determine if the stime parameter is valid
if ($now-$stime >) {
die ("Request timed out");
}
Determines whether the nonce parameter already exists in the "set" (
In_array ($nonce, $nonceArray)) {
die ("request only once valid");
}
Verify the digital signature
if ($sign!= MD5 ($uid. $token. $stime. $nonce)) {
Die (digital signature verification failed);
/* IF ($now-$nonceArray->lastmodifytime >) {
$nonceArray = null;
}
$nonceArray. push ($nonce);
*
//handling random number
$key = ' nonce ' + $uid;
if ($redis->sismember ($key, $nonce) = = True) {
die (' Deny replay attack request ');
}
if ($redis->scard ($key) > 90000) {
$redis->del ($key);
}
$redis->sadd ($key, $nonce);
Replay attack Check Complete
Reference articles:
Http://www.360doc.com/content/14/0116/16/834950_345740386.shtml