Front-end encryption

 

1.1 Overview of front-end js encryption

The system security requirements are relatively high, so you need to choose the https protocol to transmit data. Of course, for general web sites in many cases, if the security requirements are not very high, the http protocol is sufficient. In this case, the plaintext transmission of the password is obviously inappropriate, because if the request is intercepted during the transmission, you can log in to the website directly with the plaintext password. 
HTTPS (443) adds SSL (Secure Sockets Layer) protocol to HTTP (80). SSL relies on certificates to verify the identity of the server and encrypts the communication between the browser and the server. Before transmission, use the public key to encrypt, and the server side uses the private key to decrypt.

For the encryption of the web front-end that uses the http protocol, it can only prevent the gentleman but not the villain. The front end is completely exposed, including your encryption algorithm
Knowing the encryption algorithm, the password can be cracked, it is only a matter of time. Please see an article on Zhihu: Fight against drag libraries

Therefore, encryption is to increase the time cost of cracking. If the time required for cracking is unacceptable, this will achieve the goal .

In order to ensure that the passwords stored in the database are more secure, a variety of one-way (asymmetric) encryption methods need to be mixed in the back-end for encrypted storage.

The front-end encryption and the back-end need to be decrypted, so a symmetric encryption algorithm is required, that is, the front-end uses encrypted = encrypt(password+key), and the back-end uses password = decrypt(encrypted +key). The front-end only transmits the encrypted string encrypted with the password and key. In this way, even if the request is intercepted, the encryption algorithm is known, but it is difficult to crack the plaintext password due to the lack of key. So this key is very important. And this key is generated and destroyed by the back-end control, and it becomes invalid when it is used up, so even if the encrypted password can be used to send a simulated login request, but the key has expired, the back-end cannot be verified.

Note that if the local environment is inherently insecure and the key is known , the password can be cracked by the decryption algorithm in an instant. Here it is just assumed that the situation was intercepted during transmission. Therefore, front-end encryption cannot prevent villains . If you really want to prevent it, you can compress and encrypt the js file of the encryption algorithm, and constantly update the method to make the js file difficult to obtain, making it difficult for hackers to obtain the encryption algorithm. This is how the perverted google does it. It implements a js virtual machine by itself, and makes encryption algorithms difficult to obtain by constantly updating encrypted and obfuscated js files. In this way, hackers cannot crack without knowing the encryption algorithm.

Here the key is generated by the server when the page is loaded and saved in a hidden field.

1.2.3 Java-side encryption and decryption (PKCS5Padding is consistent with Pkcs7 of js)

package com.jykj.demo.util;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;

import sun.misc.BASE64Decoder;

public class EncryptUtil {
    private static final String KEY = "abcdefgabcdefg12";  
    private static final String ALGORITHMSTR = "AES/ECB/PKCS5Padding";  
    public static String base64Encode(byte[] bytes){  
        return Base64.encodeBase64String(bytes);  
    }  
    public static byte[] base64Decode(String base64Code) throws Exception{  
        return new BASE64Decoder().decodeBuffer(base64Code);  
    }  
    public static byte[] aesEncryptToBytes(String content, String encryptKey) throws Exception {  
        KeyGenerator kgen = KeyGenerator.getInstance("AES");  
        kgen.init(128);  
        Cipher cipher = Cipher.getInstance(ALGORITHMSTR);  
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(), "AES"));  

        return cipher.doFinal(content.getBytes("utf-8"));  
    }  
    public static String aesEncrypt(String content, String encryptKey) throws Exception {  
        return base64Encode(aesEncryptToBytes(content, encryptKey));  
    }  
    public static String aesDecryptByBytes(byte[] encryptBytes, String decryptKey) throws Exception {  
        KeyGenerator kgen = KeyGenerator.getInstance("AES");  
        kgen.init(128);  

        Cipher cipher = Cipher.getInstance(ALGORITHMSTR);  
        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptKey.getBytes(), "AES"));  
        byte[] decryptBytes = cipher.doFinal(encryptBytes);  

        return new String(decryptBytes);  
    }  
    public static String aesDecrypt(String encryptStr, String decryptKey) throws Exception {  
        return aesDecryptByBytes(base64Decode(encryptStr), decryptKey);  
    }  


    /**
     * 测试
     * 
     */
    public static void main(String[] args) throws Exception {

        String content = "Test String么么哒";  //0gqIDaFNAAmwvv3tKsFOFf9P9m/6MWlmtB8SspgxqpWKYnELb/lXkyXm7P4sMf3e
        System.out.println("加密前:" + content);  

        System.out.println("加密密钥和解密密钥:" + KEY);  

        String encrypt = aesEncrypt(content, KEY);  
        System.out.println(encrypt.length()+":加密后:" + encrypt);  

        String decrypt = aesDecrypt(encrypt, KEY);  
        System.out.println("解密后:" + decrypt);  
    }
}

Guess you like

Origin blog.csdn.net/qq_43422918/article/details/114926663
Recommended