9

This is why the original 103

Hello, I am why.

As shown in the picture, replay attack, I really encountered this question during the interview, twice.

What impressed me was that when I encountered this interview question for the first time, and also when I heard the word "replay attack" for the first time, I was blinded, so I even guessed it and I was idempotent towards the interface. Answered in the direction of sex.

The result was cold.

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

The academic explanation is this:

Replay attack (English: replay attack, or replay attack) is a malicious or fraudulent form of network attack that repeats or delays valid data. This can be performed by the initiator or by an adversary who intercepts the data and retransmits the data, which may be part of a spoofing attack through IP packet replacement. This is a lower level version of the "man in the middle attack".

Another description of this attack is: "Replay the message from a different context to the expected (or original and expected) context of the security protocol, thereby deceiving other participants, causing them to mistakenly believe that the protocol operation has been successfully completed."

Give a simple example:

We programmers work day and night, get a card in the massage parlor, and occasionally go to wash your feet and relax.

One day, when I was going to wash my feet, I said to the clerk: Arrange a price of 168 for me. It’s a young man. It’s more exciting. My card number is 88888888.

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

Unexpectedly, our conversation was heard by other people, so he also told the clerk: Arrange a 168 price for me, a young man, press it more aggressively, my card number is 88888888.

I also imitated my signature and signed at the front desk.

Send the previous, normal request again, this is a replay attack.

Some friends will say: My interface is signed, shouldn't it be a problem?

What happened to your endorsement?

I haven't touched your message, so you can check your 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 receiver can verify the signature normally after receiving the message.

There is nothing wrong.

Some friends will also say: My interface is encrypted, shouldn't it be a problem?

It seems that I still don't understand the basic principles of replay attacks.

What's wrong with your encryption?

Anyway, I intercepted your message. Although your message is encrypted, it looks like a garbled code, but I don't need to know the specific content of your message. Just resend it and it's over.

Still the previous example.

Suppose I said to the clerk when I went to wash my feet: The king of heaven overpowers the tiger.

After being heard by the person next to him, he didn't even know what "the king of heaven" was.

But after he saw what I said, he was arranged for a technical service of 168 yuan.

So he also said to the clerk: the king of heaven overpowers the tiger.

Can also be arranged.

Therefore, others do not need to know the specific meaning of your message.

As long as I send it to you again, you will decrypt it and find that it can be decrypted.

Deciphering it means that the secret code is correct.

Therefore, although the message is encrypted and signed for transmission, it is of no use to prevent request replay.

Encrypted endorsement

Come, before talking about the solution, let's clarify two concepts: encryption and endorsement.

The literal meaning is not explained, everyone knows, talk about the purpose.

The purpose of encryption: In order to ensure the privacy of the transmitted information, the specific content of the transmission is not seen by others, and only the receiver can see the correct information.

The purpose of the signature: the message receiver verifies whether the information is sent by a legitimate sender, and confirms whether the information has been tampered with by others.

Whether it is encryption or endorsement, both public and private keys are involved.

Remember: public key encryption, private key signature.

Briefly talk about the principle.

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

The receiver has three things: its own private key, its own 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 is public key encryption?

Come to a rebuttal method.

Suppose the sender of the message encrypts it with its own private key. Then the message is intercepted by the middleman, because he has the public key of the sender, then the middleman can use the public key to decrypt the message and obtain the plaintext message, which will not achieve the purpose of encryption.

Therefore, the correct operation should be to use the recipient's public key to encrypt, so that even if the message is intercepted by the middleman, he does not have the recipient's private key, so the encryption cannot be decrypted and the plaintext cannot be seen.

Why is the private key signed?

Similarly, the method of contradiction.

Assume that the sender of the message signs with the public key of the recipient. If the message is intercepted by the middleman, by coincidence, I also have the public key of the recipient. Click and change the message directly, and then also signed the recipient's public key and sent it.

Such an endorsement is meaningless.

Therefore, if you have to sign with your own private key, even if it is intercepted, the middleman does not have the private key. After modifying the message, it will not be able to sign and it will be useless.

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 are talking about, I just need to re-send the intercepted request over and over again.

Therefore, it is important to endorse and verify the signature.

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

In fact, the replay attack is also a lower-level version of the "man-in-the-middle attack".

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

When I went to wash my feet, I said to the clerk: Arrange a price of 168 for me. It’s a young man. It’s more exciting. My card number is 88888888.

The conversation was overheard, and the middleman said to the clerk: Arrange a 1999 price for me. Let my sister-in-law cool off. The massage technique is better. My card number is 88888888.

Tampering with packets 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, we just think about how to do things in the fields participating in the signature.

If you can think of this, it is better to answer this question.

If you are answering this question from the perspective of data encryption, you can go back and wait for the notice.

In addition, when it comes to encryption, everyone will think of HTTPS data encryption.

So, when the interviewer asks you: Can HTTPS data encryption prevent replay attacks?

Answer: No, encryption can effectively prevent plaintext data from being monitored, but it cannot prevent replay attacks.

Next, we look at the solution.

solution

plus time stamp

First of all, the common solution is to add a timestamp to the request message and participate in the endorsement.

When the receiver receives the message, after the signature verification.

First of all, the first thing is to compare the timestamp field in the request with the local time.

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

Can you understand why there is a time tolerance range?

Because the transmission, decryption, and signature verification of the message takes time, it cannot be assumed that I will send it out in one second and the server will receive it in the next second.

Therefore, there must be a time tolerance range.

But this fault tolerance range brings another problem.

Replay attacks cannot be completely avoided.

At least within the time tolerance range, such as 60 seconds, the server considers the re-sent request to be valid.

So what to do?

plus random string

To put it another way, we add a random string to the request message, and then let it participate in the signature.

After receiving the message, the recipient takes out the random string after verifying the signature to determine whether the random string has been processed. For example, determine whether it exists in Redis.

When the request to replay it again, I took a look: Oh, good guy, this random string has already been used, and it won't be processed.

In this case, the random string must be unique and unique in history.

Because you may receive a request that was replayed a few days ago.

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

I still have to store it, and the amount of stored data will continue to grow, is it a bit troublesome?

It's really troublesome.

This idea is very similar to using the globally unique serial number to ensure the idempotence of the interface.

Therefore, when I encountered this interview question for the first time, I answered it from the perspective of interface idempotence, and I couldn't say that the answer was wrong.

It can only be said that the answer is not the standard answer that the interviewer wants.

So what is the answer that the interviewer wants to hear?

timestamp + random string

The problem of timestamp is that there is a certain time error tolerance window, and replay attacks within this time window cannot be prevented.

The problem with random strings is to ensure that the history is globally unique, and keeping random strings becomes a troublesome thing.

So when we knead these two schemes together, something magical happens:

I just need to ensure that the random strings generated within the time window are not repeated.

And assuming that the time window is 60 seconds, we use Redis to record the random string that has appeared, then the timeout period of this string in the background is set to 60 seconds.

Generally speaking, this time window will not be too long. I have connected to so many various channels, and the longest I have seen is only 5 minutes.

To ensure that the two random strings generated within 5 minutes are not repeated, this requirement is much easier to achieve than to ensure that a serial number that is globally unique in history is realized?

In addition, the most critical sentence must be said: timestamp and random string must participate in the signing logic.

Isn't this easy to understand?

The receiver sees whether the message has been tampered with, and sees whether the signature can be matched.

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

If your timestamp and random string do not participate in the endorsement, then arbitrarily modifying the timestamp or random string will not cause a change in the signature. Isn't it a waste of work?

The middleman intercepted the request with a click and found that there was a timestamp and a random string. When he was about to give up, he thought of the dead horse as a living horse doctor, changed the random string, and threw it to the recipient.

As a result, the correct response was received.

If I were the middleman, I would laugh out loud: the programmer who wrote this code is too cute, right?

WeChat Pay

In fact, when it comes to timestamp and random string, I think of WeChat Pay.

When I first entered the industry, I was greeted by WeChat Pay.

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

I wrote it out just to give friends who are not familiar with the endorsement a specific understanding.

Let's take a look at the interface document of WeChat Pay:

https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6

You can see that there are indeed timestamps (timeStamp) and random strings (nonceStr) in the request parameters, and they have also been specially bolded:

The parameters involved in signing are: appId, timeStamp, nonceStr, package, signType, and the parameters are case sensitive.

So how did you sign it?

The official also gave a detailed explanation:

https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3

The first is to sort all non-empty fields that need to be signed in lexicographic order. And use the format of URL key-value pairs (ie key1=value1&key2=value2...) to be spliced into a string stringA.

Then, at the end of stringA, splice the key (merchant key) to get the stringSignTemp character string, and perform MD5 operation on stringSignTemp, and then convert all characters of the obtained character string to uppercase to get the sign value signValue.

The official gave an actual case, as follows:

Let me say it again: Although there are timestamps and random strings in the WeChat payment interface, the purpose is not to prevent replay attacks. Written here is just to give everyone a specific understanding of the process of signing.

Stop the whole crop.

So what is the purpose of adding random strings to the interface?

The official 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 obtained value into a string.

Ali API Gateway

After reading WeChat Pay, let's take a look at how Ali's API gateway prevents replay attacks.

https://help.aliyun.com/knowledge_detail/50041.html

Ali's API gateway adds two parameters to the HEADER: X-Ca-Timestamp and X-Ca-Nonce.

The solution is to add a random string to the timestamp we mentioned earlier.

Then look at its signature generation process.

First, the client generates a signature, three steps:

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

A picture is worth a thousand words:

Then the server verifies the signature, four steps:

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

The specific signature algorithm is actually similar to WeChat Pay, and it is mainly lexicographically sorted for the fields participating in the signature.

The differences are not explained by comparison, and interested friends can take a look for themselves.

One last word

Okay, after seeing this, please give me a thumbs up. Zhou is very tired and needs a little positive feedback.

If you are too talented or knowledgeable, there will inevitably be mistakes. If you find something wrong, you can raise it in the message area and I will modify it.

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


why技术
2.2k 声望6.8k 粉丝