How to interact with the front and rear side API to ensure data security? (turn)

Foreword

Before and after the end of the separation development approach, our interface is a standard to promote good interface definition, each developed its own function, and finally with adjusted closing. Whether developing or native APP webapp or PC-side software, as long as the front and rear ends of the separation mode, it can not avoid the call interface provided to the back-end business interactions.

Web page or app, just grabbed the package can be clearly aware of this request to obtain data, such an interface for reptiles engineer is a blessing, just to catch your data easy.

Data security is very important, especially information related to the user, the slightest mistake will be hijacked by criminals, so we should attach great importance to this, can not tolerate sloppy.

How to ensure the safety of the API call data?

  1. Communication use https

  2. Request signature, preventing parameter tampering

  3. Identification mechanism, each request must verify the legality

  4. APP is used to prevent the capture operation ssl pinning

  5. Request and response for all encryption and decryption operations

  6. And so on ...... program.

Request and response for all encryption and decryption operations

There are many programs, when you do more, which means higher security, today I am with you to introduce all requests and responses for both encryption and decryption operations of the program, even if we can capture, even if I can call interface, but I returned data is encrypted, the encryption algorithm is secure as long as enough, you got my encrypted content have no effect on me.

Like this work best to make a unified process, you can not let go of each development are concerned about this matter, so that if each developer to pay attention to this matter is very troublesome, had encryption manual call return data the method, when data is received at the calling method have decryption.

For this reason, I based Spring Boot encapsulates a Starter, built-in AES encryption algorithm. GitHub at the following address:

https://github.com/yinjihuan/spring-boot-starter-encrypt

Let's look at how to use, you can download the source code, you can then introduced, and then increase @EnableEncrypt comment on the boot open class encryption and decryption operations:

@EnableEncrypt
@SpringBootApplication
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

Adds encryption key configuration:

spring.encrypt.key=abcdef0123456789
spring.encrypt.debug=false
  • spring.encrypt.key: encryption key, must be 16

  • spring.encrypt.debug: whether to open the debug mode, the default is false, if true is not enabled encryption and decryption operations

In order to be considered universal, it does not perform encryption and decryption for all requests, do the annotation-based control

The response data to be encrypted, then the Controller in a method to add annotations @Encrypt.

@Encrypt
@GetMapping("/list")
public Response queryNews(String city) {
    return Response.ok(city);
}

When we visit / list interface format of the returned data is base64 encoded after encryption.

Another operational data submitted by the preceding paragraph is divided into two cases, one is get request, this time being no deal, then consider later, post requests currently only processing, submission based json format, that is to say the background @RequestBody need to receive data for the job, we need to decrypt operations plus @Decrypt to comment.

@Decrypt
@PostMapping("/save")
public Response savePageLog(@RequestBody PageLogParam logParam, HttpServletRequest request) {
    pageLogService.save(logParam);
    return Response.ok();
}

@Decrypt added annotation, the front end of the data submitted in accordance with the AES encryption algorithm requires, are encrypted, and then submitted to a rear end, a rear end side will be automatically decrypted, and then mapped to the parameter object.

Explained above are the back-end code, if we use the front js to explain, of course, you can also use other languages ​​to do, if it is a native Android app is using java code to handle.

The front end needs to be done on two things:

  1. Unified treatment response data, decrypt operations before rendering the page

  2. When a POST request data is sent, the encrypted unified

js file encryption please refer to my GitHub in encrypt the aes.js, crypto-js.js, pad-zeropadding.js

We axios as request data frame, with axios interceptors encryption and decryption operations to the unitary

Js all, to package a class encryption and decryption, it is noted that the encrypted key and the needs of the background, or to each other can not be decrypted, as follows:

var key  = CryptoJS.enc.Latin1.parse('abcdef0123456789');
var iv   = CryptoJS.enc.Latin1.parse('abcdef0123456789');
// encryption
function EncryptData(data) {
    var srcs = CryptoJS.enc.Utf8.parse(data);
    var encrypted = CryptoJS.AES.encrypt(srcs, key, {
        mode : CryptoJS.mode.ECB,
        padding : CryptoJS.pad.Pkcs7
    });
    return encrypted.toString();
}
// decryption
function DecryptData(data) {
    var stime = new Date().getTime();
    var decrypt = CryptoJS.AES.decrypt(data, key, {
        mode : CryptoJS.mode.ECB,
        padding : CryptoJS.pad.Pkcs7
    });
    var result = JSON.parse(CryptoJS.enc.Utf8.stringify(decrypt).toString());
    var etime = new Date().getTime();
    console.log("DecryptData Time:" + (etime - stime));
    return result;
}

axios interceptor unified handling code:

// add request interceptor
axios.interceptors.request.use(function (config) {
    // Please encrypt all POST, json data must be submitted, the form is not supported
    if (config.method == "post") {
        config.data = EncryptData(JSON.stringify(config.data));
    }
    return config;
  }, function (error) {
    return Promise.reject(error);
});
// add response interceptor
axios.interceptors.response.use(function (response) {
    // Returns the string representation of the back-end needs decryption operation
    if(typeof(response.data) == "string"){
        response.data = DecryptData(response.data);
    }
    return response;
  }, function (error) {
    return Promise.reject(error);
});

So far, we do for the entire communication before and after the end of the interaction of an encryption operation as long as the encryption key does not leak, others get your data is useless, the question is how to ensure that key does not leak it?

High security server can be stored in the database or configuration file, after all, on our own server, the most dangerous in fact when the front end, app fortunately, can be packaged, but to prevent decompilation and so on.

If webapp you can rely on encryption to achieve js, Now I get to introduce a dynamic encryption key manner, but more complex to implement, we are not on the code, we talk about ideas:

Encryption algorithms symmetric encryption and asymmetric encryption, AES is a symmetric encrypt, RSA-asymmetric encryption. The reason to use AES encryption of data because of the high efficiency, RSA is running slow, can be used for signing operation.

We can use these two complementary algorithms to ensure the safety of using RSA encryption to AES secret key transmitted using AES to encrypt data, a combination of both, complementary advantages.

In fact, we understand the principles of HTTPS, then for the following content should be the one to understand, HTTPS because you want client and server securely negotiate a symmetric encryption algorithm than the reasons for the slow HTTP. The rest is the communication parties use this symmetric encryption algorithm for encryption and decryption.

  1. Client starts, sends a request to the server, the server generates a pair of public and private keys using the RSA algorithm, we referred to as pubkey1, prikey1, the public key pubkey1 returned to the client.

  2. After the client to get the public pubkey1 returned from the server, generate their own RSA algorithm with a public and private key, we referred to as pubkey2, prikey2, and public pubkey2 public key encryption pubkey1, after the encrypted transmission to the server .

  3. At this time, the server receives the ciphertext transmitted from the client, with the private key to decrypt prikey1, since the data is encrypted with the public key pubkey1, can be obtained by decrypting a client-generated public key pubkey2

  4. After then himself in to generate symmetric encryption, which is our AES, in fact, is relative to the length of the encryption key that we configured in 16, we generated the key is encrypted with the public key pubkey2, returned to the client, because only the client has a corresponding private key prikey2 pubkey2, only the client can decrypt, after the client to get the data, decrypting operation with prikey2, get the key AES encryption, and finally encrypts data transmission using the encryption key, the end of the entire process so far .

spring-boot-starter-encrypt原理

Finally, we come to the simple principle of spring-boot-starter-encrypt introduced under the bar, but also so that we can understand why the Spring Boot so easy, simply click on the configuration can achieve a lot of features.

@EnableEncrypt annotations on class is started to enable the function by introducing automatic configuration based @Import

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({EncryptAutoConfiguration.class})
public @interface EnableEncrypt {
}

EncryptAutoConfiguration class configuration request and response process, using the Spring and RequestBodyAdvice ResponseBodyAdvice, statistical processing of the request is convenient in Spring. If you have more to package it from the underlying servlet to handle a piece.

@Configuration
@Component
@EnableAutoConfiguration
@EnableConfigurationProperties(EncryptProperties.class)
public class EncryptAutoConfiguration {
    /**
     * Configuration request decryption
     * @return
     */
    @Bean
    public EncryptResponseBodyAdvice encryptResponseBodyAdvice() {
        return new EncryptResponseBodyAdvice();
    }
    /**
     * Encryption configuration request
     * @return
     */
    @Bean
    public EncryptRequestBodyAdvice encryptRequestBodyAdvice() {
        return new EncryptRequestBodyAdvice();
    }
}

By RequestBodyAdvice and ResponseBodyAdvice can do processing in response to the request, and the principle is probably so much.

Guess you like

Origin www.cnblogs.com/fifteen-wu/p/11080166.html