Recently, when I was reviewing the project, I thought of the requirement of front-end encryption and verification. I felt that there were few articles about this area, so I sorted out this content, hoping to help friends who need this area in the future.

Below you’ll see:

  • Requirement analysis and technology selection
  • RSA Encryption Practices
  • RSA + SHA256 verification practice
  • Potholes in project practice
  • How to deal with the problem of large dependent packages

First let’s start with requirements ☟

Why introduce encryption and verification?

It starts with two things

  1. The company commissioned a third party security inspection to scan and find that there are security loopholes in the login part of the account, that is, the password security problem;
  2. We found that the ordering interface of the project was often maliciously brushed by a certain platform.

So here’s what we need:

  1. The password must be encrypted for account login.
  2. Order interface to avoid the impact of malicious brushing;

Requirement analysis and technology selection

Requirements: 1

The requirement here is clear: the login password needs to be encrypted, so the next step is to find a suitable encryption scheme. Here we do not have too much confusion, directly choose the current popular and relatively secure RSA asymmetric encryption.

Requirement 2:

Before analyzing the requirements, let’s first look at how malicious brushing works.

When the other party knows the parameters required by our ordering interface and the basic back end verification rules, it can directly skip the front end verification, make slight changes to the parameters, and call the ordering interface frequently through the program.

To prevent this behavior, we need to do two things:

The first point is interface throttling processing, which is back-end processing, not introduced here;

The second point is the order interface check, which requires the front end to generate the signature and the back end to carry out the check comparison, the specific check comparison between the front and back end;

The next problem is to choose a suitable technical scheme for the verification. At present, there are many schemes to deal with the verification, such as MD5, SHA1, SHA256, etc. Which one to choose, we must be combined with the specific use of the scenario to analyze.

First of all, the project I need to deal with is a Saas platform serving more than 3000 scenic spots. The concurrency of the single interface is relatively large, so there are requirements on the concurrency performance (the concurrency pressure here is in the back end). Secondly, the fundamental requirement is to avoid being brushed, so security is also an important standard to measure.

Then, the back-end colleagues use MD5, SHA1, and SHA-256 signatures according to the agreed signature rules. The time required to generate signatures for the same number of times is compared as follows:

# 100 times (ms) 10000 times (ms) 1000000 times (ms)
MD5 161 9018 883387
SHA1 166 8980 886486
SHA256 2121 10590 931271

As can be seen from the data comparison table above, when the number of words executed is relatively small, the execution efficiency of MD5 and SHA1 is obviously better, but after the number of executions reaches more than 10,000 times, the total execution time gap between the three does not increase. Finally, by considering security and server capacity, SHA256 is finally determined to generate signatures. Although it is relatively performance costly, it is perfectly affordable on current back-end servers, plus it can provide better security.

Here, we will determine the specific technical scheme, and then enter the specific encryption and verification practice

RSA Encryption Practices

Introduction to the

In 1977, three mathematicians Rivest, Shamir, and Adleman devised an algorithm that could implement asymmetric encryption. The algorithm, named after all three of them, is called RSA. Since then, RSA has been the most widely used “asymmetric encryption algorithm”. It is no exaggeration to say that wherever there is a computer network, there is an RSA algorithm.

More on the PRINCIPLE of RSA algorithm, which can open the lower portal:

Principle of RSA Algorithm (1) Principle of RSA Algorithm (2)

The working process

To facilitate your understanding, I first draw a WORK flow chart of RSA encryption.

Specific steps:

  • Step1: User input information, front-end use public key encryption
  • Step2: send the ciphertext to the back end through an HTTP request
  • Step3: the back end uses the private key to decrypt ciphertext

Here you should notice two key words:

Public key — a publicly available secret key, usually used front-end, for text encryption

Private key – A non-public secret key, usually reserved for use by the back end to decrypt encrypted text

Add: in fact, you can also use private key encryption, public key decryption, as long as part of the private can be kept

Auxiliary tool

  • Tool 1: RSA Public and Private key Generation website: click here

Let’s see what it looks like

/ / PUBLIC KEY -- -- -- -- -- BEGIN PUBLIC KEY -- -- -- -- -- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5iTKIXHGuDNG9x... 3QIDAQAB -----END PUBLIC KEY-----Copy the code
/ / PRIVATE KEY -- -- -- -- -- BEGIN PRIVATE KEY -- -- -- -- -- MIIEuwIBADANBgkqhkiG9w0BAQEFAASCBKUwggShAgEAAoIBAQDmJMohcc... 8jKcsEAozBoeXJiSx0+D -----END PRIVATE KEY-----Copy the code

The public and private keys have been commented here, which we need to keep for later development.

  • Tool 2: RSA Encryption and decryption verification website: Click here

Encryption test: Select RSA Public Key encryption >> Enter the public key >> Enter the content to be encrypted >> Encryption result

In the figure, we input Hello world encryption to get:

cTX3VGKEjxGYl0d35JfENIPgtB3amNEWbjjlMw8vMcIUCzM6gHvZwbTjkHvuKDKJGQf0Upcb1zRVsDwWYb8MBYlOia72pme29M6UuRyt4FYy0mL8GTLNJUMc GP+lI9jb2tQ7NmToufV2RI9c666P6B+xx5bT4vHEgI+hs4xKny8=Copy the code

Decryption test: Select RSA private key for decryption >> Enter the private key >> Enter the content to be decrypted >> Original text

After decryption, we remeet the original: Hello world ✌

Implementation in code

Here, we need to use JSEncrypt to complete the front-end RSA encryption

  1. Install dependencies
npm install jsencrypt --save
Copy the code
  1. Create our class method
// Create a new file /common/ myencrypt.js
import { JSEncrypt } from 'jsencrypt';
class myEncrypt {
  constructor() {
    // Do not remove comments here
    this.pubsKey = ` -----BEGIN PUBLIC KEY----- SIb3DQEBAQUAA4GNADCBiQKBgQDI5kmdW9rmxQlTraZ6Wx+C7kYR...... Omit -----END PUBLIC KEY----- ';
  }
  /** * RSAj encryption *@param {String} Text Indicates the text to be encrypted@returns {String} Encrypted text */
   setRSA(text) {
    // Create a JSEncrypt object
    const encryptor = new JSEncrypt();
    // Set the public key
    encryptor.setPublicKey(this.pubsKey);
    // Encrypt data
    const resultText = encryptor.encrypt(text);
    // Transcode to avoid the loss of special symbols during transmission
    return encodeURIComponent(resultText); }}export default new myEncrypt();
Copy the code
  1. Encryption processing
// Introduce this method
import encrypt from '@/common/myEncrypt';
// Encrypt the user password
const password = '996ICU';
const rsaPass = encrypt.setRSA(password);
Copy the code

Note: The window object cannot be used in the wechat applet. Direct reference to the dependency processing will cause an error. Jsencrypt needs to be modified for compatibility. ☞ Use jsencrypt.js in small programs

SHA256 Generates a signature

Introduction to the

Sha-2, named after Secure Hash Algorithm 2, is a cryptographic Hash function Algorithm standard developed by the U.S. National Security Agency and published by the National Institute of Standards and Technology (NIST) in 2001. It is an SHA algorithm and a successor to SHA-1. There are six different algorithm standards, including SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, and SHA-512/256.

SHA256 algorithm principle see this article to understand the SHA256 algorithm principle and implementation

The working process

Without further ado, let’s get right to the picture

Specific steps:

  • Step1: The user submits the order, and the front end generates the signature
  • Step2: at the gateway layer, the back-end generates signatures according to the rules agreed by both parties for comparison
  • Step3: Compare and pass the normal ordering process

Here we focus on the rules for generating signatures in the front end

  1. Converts the interface argument to the string A;
  2. Generate random string as salt value S;
  3. Firstly, the interface parameter string is processed to generate the signature, then the salt value is merged with the previously generated signature, and the SHA256 algorithm is continued to generate the new signature, and the formula issha256(sha256(A)+S);
  4. Use RSA to encrypt salt values;
  5. The encrypted salt value and the generated check label are passed to the back end for convenient verification.

Implementation in code

Here I recommend using the sha256 module in hash.js to generate checkers, and I’ll explain why I chose it later.

  1. Install dependencies
// SHA256 generates verification NPM install hash.js --saveCopy the code
  1. To generate the signature
// common/myEncrypt.js 
/ / myEncrypt class
/** * generates a check *@param {Object} Params request parameter *@param {Boolean} IsJson Whether it is a JSON request */
setSign(params, isJson) {
  // Random string, omit generation rule here
  constsalt = .. sfoshx2434.. ;// Handle the interface parameters, which can be handled according to the rules predetermined with the backend
  const paramsStr = dataToString(params, isJson); 
  const sign = this.signData(paramsStr, salt);
  const sk = this.setRSA(salt);
  return {
    sk,
    sign,
  };
}
/** * Generate check * according to convention rules@param {String} Data Indicates the data to be encrypted@param {String} Salt salt value * /
signData(data, salt) {
  const once = sha256().update(data).digest('hex');
  const seconed = sha256().update(once + salt).digest('hex');
  return seconed;
}
Copy the code
  1. Interface.
import myEncrypt from '@/common/myEncrypt';
Params is the interface parameter. JsonFlag is the parameter type
const {sk, sign} = myEncrypt.setSign(params, jsonFlag);
Copy the code

Mining pit inventory.

  1. The encrypted RSA ciphertext needs to be transcoded using encodeURIComponent and then transmitted to the back end. Because special symbols such as + signs exist in ciphertext, they are easily lost during interface transmission.
  2. RSA encryption depends on Jsencrypt. Because jsencrypt contains window objects, it is used in small programs and requires compatibility processing.
  3. At first, the most commonly used package of crypto-js was selected to provide SHA256 algorithm. Later, when used in the small program, the package size directly exploded. The volume of crypto-js is 434KB, while the volume of hash.js we use now is only 41.7KB. In fact, I also tried to use JS-SHA256 to generate check labels. Although the volume is relatively small, it often fails to match the back end after check labels, so IT has to be abandoned.

Afterword.

In fact, front-end encryption or do interface check signature is not absolute security, encryption can be cracked, signature can imitate, do these work is just to those who want to make things difficult. Finally hope this article can help everyone, thanks ❤.