This is why’s 103rd original article

Hello, I’m Why.

The picture, replay attack, I’ve actually had this problem in an interview, twice.

What impressed me most was that when I first encountered this interview question and heard the word “replay attack” for the first time, I was so confused that I answered it in the direction of interface idempotence even with guessing.

As a result, it gets cold.

To answer how to prevent replay attacks, we need to know what replay attacks are.

The academic explanation goes like this:

Replay attack (English: replay attack, also called replay attack) is a malicious or fraudulent form of network attack that duplicates or delays valid data. This can be done by the originator or by an adversary that intercepts and retransmits the data, possibly as part of a spoofing attack via IP packet substitution. This is a lower-level version of a man-in-the-middle attack.

Another description of this attack is: “Replaying a message from a different context into the intended (or original and expected) context of the security protocol, thereby fooling other participants into thinking they have successfully completed the protocol run.”

Here’s a simple example:

We programmers work hard day and night. It’s not too much to get a card in a massage parlor and wash your feet once in a while to relax.

One day, I went to wash the feet of the time said to the shop assistant: give me an arrangement of 168 price, to the young man, according to the comparison of strength, my card number is 88888888.

Then I signed my name at the front desk and the clerk arranged for a burly young man to give me a massage.

I didn’t think our conversation was overheard by others, so he also said to the shop assistant: give me a price of 168, to the young man, according to the more exciting, my card number is 88888888.

He imitated my signature and signed it at the front desk.

This is a replay attack, in which the previous, normal request is sent again.

Some friends will say: my interface is signed, should be no problem?

What happened to the sign?

I did not touch your message, so you can also check the signature normally.

Not only did I copy the normal fields in your message, but I also copied all the signatures in the message.

Therefore, the receiving party can check the signature after receiving the packet.

There’s nothing wrong with it.

Some friends will also say: my interface is encrypted, should be no problem?

Still don’t seem to understand the basics of replay attacks.

What happened to your encryption?

Anyway, I intercepted your message. Although your message is encrypted, it looks like a piece of garbled code to me, but I don’t need to know the specific content of your message, so I can directly resend it.

Again, the previous example.

Suppose I go to wash my feet and say to the shop assistant, “Heaven covers earth.

By the side of the people heard, he did not know “tianwang cover tiger” is what.

But after he saw me say this sentence, he was arranged a 168 yuan technical service.

So he also said to the shop assistant: Tianwang cover tihu.

Can also be arranged.

Therefore, no one needs to know the exact meaning of your statement.

As soon as I send it to you again, you decrypt it and find it works.

Decryption means the codes are right.

Therefore, even though the message is encrypted and checked, it is of little use to prevent the request from being replayed.

The signature of the encryption

Before we get to the solution, let’s clarify two concepts: encryption and signing.

I don’t want to explain the literal meaning, but we all know the purpose.

The purpose of encryption is to ensure the privacy of transmitted information and prevent other people from seeing the specific content. Only the correct information can be seen by the recipient.

The purpose of signing: The recipient verifies that the message was sent by a legitimate sender and that the message has not been tampered with by others.

Both encryption and signing involve public and private keys.

Remember: public key encryption, private key signature.

Just a quick explanation of how this works.

The sender has three things: its private key, its public key, and the receiver’s public key.

The receiver has three things: its private key, its public key, and the sender’s public key.

The middleman has two things: the public key of the receiver and the public key of the sender.

Why public key encryption?

Let’s do a contradiction.

Assume that the message sender encrypts it with its own private key. Then the message is intercepted by the middleman, because he has the sender’s public key, the middleman can decrypt the message with the public key and obtain the plaintext message, thus failing to achieve the purpose of encryption.

Therefore, the correct operation is to encrypt the message with the receiver’s public key, so that even if the message is intercepted by the middleman, he does not have the receiver’s private key, so he cannot decrypt the secret and see the plaintext.

Why is private key signed?

Likewise, reduction.

Assume the sender of the message, signed with the receiver’s public key. If the message is intercepted by an intermediary, incidentally, I also have the recipient’s public key. Click, change the message directly, then also take the recipient’s public key signed, sent over.

This signing is meaningless.

Therefore, if you want to use your own private key to sign the message, even if it is intercepted, the middleman does not have a private key, and after modifying the message, you cannot get the signature, so there is little use.

As mentioned earlier, for replay attacks, it doesn’t matter whether the intercepted content is encrypted or not. Because I don’t need what you’re saying, I just need to re-send the intercepted request over and over again.

Therefore, it is important to sign and check.

If you can modify the packet and re-sign it, it’s not called a replay attack, it’s called a man-in-the-middle attack.

A replay attack is a lower-level version of a man-in-the-middle attack.

What is a man-in-the-middle attack?

When I go to wash feet, say to the shop assistant: arrange a 168 price for me, want young man, press more take strength, my card number is 88888888.

The conversation was overheard, the middleman said to the clerk: Give me a 1999 price, to sister-in-law cool ah, massage a little better, my card number is 88888888.

Tamper with the packet. This is a man-in-the-middle attack.

This article focuses on solutions to replay attacks.

After the previous analysis, we know that to solve the replay attack, is to think about how to do things in the field of the signature.

Thinking about this is a good way to answer this question.

If you’re answering this question from a data encryption perspective, you can go back and wait.

Also, when it comes to encryption, most people think of HTTPS data encryption.

So, when an interviewer asks you: Does HTTPS data encryption protect against replay attacks?

A: No, encryption effectively prevents plaintext data from being listened to, but it does not prevent replay attacks.

Next, let’s look at solutions.

The solution

Add a timestamp

First, a common solution is to add a time stamp to the request message and participate in the signing.

When the receiver receives the packet, it is checked.

The first thing to do is compare the timestamp field in the request with the local time.

If the time error is within a specified time, say 60 seconds, then the request is considered reasonable and the program can continue processing.

Why should there be a time tolerance, okay?

Since it takes time to transmit, decrypt, and verify a packet, it cannot be assumed that the server will receive it the next second after I send it.

So, you have to have a time margin for error.

But this fault-tolerant range presents another problem.

Replay attacks cannot be completely avoided.

At least within the time tolerance range, such as 60 seconds, the server considers a resent request valid.

So what to do?

Add random string

To change the way we think about it, we add a random string to the request message and let it participate in the signing.

The receiving party receives the message, checks the signature, and takes out the random string to determine whether the random string has been processed. For example, check whether it exists in Redis.

When the request again put over the time, a look: ho, good guy, this random string has been used ah, not processing.

In this case, the random string has to be unique, historically and globally unique.

Because you don’t know when you’re going to get a rerun request from a few days ago.

It does solve the problem of requesting replay, but the downside is obvious: history is globally unique.

I’m going to have to store it, and it’s going to keep getting bigger and bigger, isn’t that a bit of a hassle?

Yes, it is.

The idea is similar to using globally unique serial numbers to ensure interface idempotency.

So, when I first came across this interview question, I tried to answer it from the perspective of interface idempotent, but I couldn’t say it was wrong.

Let’s just say it’s not the standard answer the interviewer is looking for.

So what do interviewers want to hear?

Timestamp + random string

The problem with timestamps is that there is a certain time tolerance window within which replay attacks cannot be defended.

The problem with random strings is that to ensure that history is globally unique, saving random strings becomes a hassle.

So when we put these two plans together, something amazing happens:

I just need to make sure that the random string generated in the time window is not repeated.

And assuming the time window is 60 seconds, we use Redis to record the random string, so the timeout time of this string in the background is set to 60 seconds.

Generally speaking, this window is not very long, I have connected with so many different channels, the longest I have seen is 5 minutes.

Ensuring that two random strings generated within 5 minutes do not duplicate each other is a much easier requirement than ensuring that a historically globally unique serial number is implemented.

In addition, the key word must be said: time stamps and random strings are involved in the checkout logic.

That makes sense, right?

The receiver sees if the paper has been tampered with, and sees if the signature matches.

The result of the signature is directly related to the value of the field involved in the signature.

If your timestamp and random string do not participate in the signing, then any modification of the timestamp or random string will not cause the signature to change, then it is not a waste of work?

The middleman clicks the request, finds a timestamp and a random string, and is about to give up, thinking dead as a doctor, changes the random string and throws it back to the receiver.

The correct response was received.

If I were the middleman, I would laugh: isn’t the programmer who wrote this code cute?

WeChat pay

In fact, when it comes to time stamps and random strings, I think of wechat Pay.

When I just entered the line, I was docile and docile by this wechat payment.

However, it should be noted that although the interface document also has timestamp and random string, but the purpose is not to prevent replay attacks.

Write it out just for the sake of signing this thing is not familiar with friends have a specific cognition.

Let’s take a look at the interface document of wechat Payment:

Pay.weixin.qq.com/wiki/doc/ap…

TimeStamp and nonceStr (nonceStr);

The parameters of the signature are appId, timeStamp, nonceStr, Package and signType, which are case sensitive.

So how is it signed?

Officials also gave detailed instructions:

Pay.weixin.qq.com/wiki/doc/ap…

The first is to sort all the non-empty fields that need to be signed in lexicographical order. And use the format of URL key-value pairs (that is, key1= Value1 &key2=value2…) Concatenated to the string stringA.

Then, the stringA is concatenated with key (merchant key) to obtain the stringSignTemp string, and MD5 operation is performed on stringSignTemp, and all characters of the string are converted to uppercase to obtain the sign value signValue.

Officials gave an actual case as follows:

Once again: wechat Pay interface, although there is a timestamp and random string, but the purpose is not to prevent replay attacks. This is just to give you a concrete understanding of the signing process.

Cut the stubble.

So what’s the purpose of adding a random string to the interface?

The authorities themselves have said:

The wechat Payment API interface protocol contains the field nonce_str, which mainly ensures that the signature is unpredictable. We recommend the following random number generation algorithm: call the random number function to generate, and convert the value to a string.

Ali API Gateway

After watching wechat Pay, take a look at how Ali’s API gateway prevents replay attacks.

Help.aliyun.com/knowledge_d…

HEADER: x-ca-timestamp, x-ca-nonce

The solution is the timestamp plus random string we talked about earlier.

Then look at its signature generation process.

First, the client generates the signature in three steps:

  • 1. Extract key data from the original request and get a signature string
  • 2. Use encryption algorithm and APP Secret to encrypt key data signature string and obtain signature
  • 3. Add all headers related to the signature to the original HTTP request to obtain the final HTTP request

A picture is worth a thousand words:

Then there are four steps to verify the signature on the server:

  • 1. Extract key data from the received request to obtain a signature string
  • 2. Read the APP Key from the received request and query the corresponding APP Secret
  • 3. Use encryption algorithm and APP Secret to encrypt key data signature string and obtain signature
  • 4. Read the client signature from the received request and compare the consistency between the server signature and the client signature.

In fact, the specific signature algorithm is similar to wechat Payment, mainly in lexicographical order for the fields participating in the signature.

The difference will not be compared, interested friends can have a look.

One last word

Okay, give it a thumbs up when you see it. Chow is more tired and needs some positive feedback.

If you find something wrong, you can put it up in the comments section and I will correct it.

Thank you for reading, I insist on original, very welcome and thank you for your attention.