The use of RSA asymmetric encryption and AES symmetric encryption in actual projects


foreword

In the project, I happened to encounter the steps of encrypting private parameters, so I deliberately learned two examples of asymmetric encryption and symmetric encryption.


1. What is symmetric encryption and asymmetric encryption?

1.1. Introduction to Symmetric Encryption

Symmetric encryption is the fastest and simplest encryption method, and the same secret key is used for encryption and decryption .

Symmetric encryption usually uses a relatively small key, generally less than 256 bits. Because the larger the key, the stronger the encryption, but the slower the encryption and decryption process.

A major disadvantage of symmetric encryption is the management and distribution of keys. In other words, how to send the keys to the hands of those who need to decrypt your messages is a problem. In the process of sending the key, there is a great risk that the key will be intercepted by hackers. The usual practice in reality is to asymmetrically encrypt the symmetric encryption key and then transmit it to those who need it.

Symmetric encryption, the encryption speed is very fast, suitable for occasions where data is often sent. The disadvantage is that the transmission of the key is cumbersome, common aes.

1.2. Introduction to asymmetric encryption

Asymmetric encryption provides a very secure method for data encryption and decryption. It uses a pair of keys, a public key and a private key. The private key can only be kept safely by one party and cannot be leaked, while the public key can be distributed to anyone who requests it. Asymmetric encryption uses one of the pair of keys to encrypt, and decryption requires the other key, the public key encrypts and the private key decrypts .
  
Asymmetric algorithm, the speed of encryption and decryption is relatively slow, suitable for occasions when sending data occasionally. The advantage is that the key transmission is convenient. Common asymmetric encryption algorithms are RSA, ECC and EIGamal

AES encryption principle
RAS encryption principle

2. RSA asymmetric encryption front-end and back-end implementation

2.1, the front end implements rsa

1. Install jsencrypt and execute the following command

npm install jsencrypt --save-dev

2. To install encryptlong, execute the following command

npm i encryptlong -S

3. Generate public key and private key
Prepare publicKey (public key) && privateKey (private key)
to generate public key and private key URL online

4. Front-end code implementation

/* 产引入jsencrypt实现数据RSA加密 */
import JSEncrypt from 'jsencrypt' // 处理长文本数据时报错 jsencrypt.js Message too long for RSA
/* 产引入encryptlong实现数据RSA加密 */
import Encrypt from 'encryptlong' // encryptlong是基于jsencrypt扩展的长文本分段加解密功能。
 
// 密钥对生成 http://web.chacuo.net/netrsakeypair
 
// 公钥key
const publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANL378k3RiZHWx5AfJqdH9xRNBmD9wGD\n' +
  '2iRe41HdTNF8RUhNnHit5NpMNtGL0NPTSSpPjjI1kJfVorRvaQerUgkCAwEAAQ=='
// 私钥key
const privateKey = 'MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEA0vfvyTdGJkdbHkB8\n' +
  'mp0f3FE0GYP3AYPaJF7jUd1M0XxFSE2ceK3k2kw20YvQ09NJKk+OMjWQl9WitG9p\n' +
  'B6tSCQIDAQABAkA2SimBrWC2/wvauBuYqjCFwLvYiRYqZKThUS3MZlebXJiLB+Ue\n' +
  '/gUifAAKIg1avttUZsHBHrop4qfJCwAI0+YRAiEA+W3NK/RaXtnRqmoUUkb59zsZ\n' +
  'UBLpvZgQPfj1MhyHDz0CIQDYhsAhPJ3mgS64NbUZmGWuuNKp5coY2GIj/zYDMJp6\n' +
  'vQIgUueLFXv/eZ1ekgz2Oi67MNCk5jeTF2BurZqNLR3MSmUCIFT3Q6uHMtsB9Eha\n' +
  '4u7hS31tj1UWE+D+ADzp59MGnoftAiBeHT7gDMuqeJHPL4b+kC+gzV4FGTfhR9q3\n' +
  'tTbklZkD2A=='
 
export default {
    
    
  /* JSEncrypt加密 */
  rsaPublicData(data) {
    
    
    var jsencrypt = new JSEncrypt()
    jsencrypt.setPublicKey(publicKey)
    // 如果是对象/数组的话,需要先JSON.stringify转换成字符串
    var result = jsencrypt.encrypt(data)
    return result
  },
  /* JSEncrypt解密 */
  rsaPrivateData(data) {
    
    
    var jsencrypt = new JSEncrypt()
    jsencrypt.setPrivateKey(privateKey)
    // 如果是对象/数组的话,需要先JSON.stringify转换成字符串
    var result = jsencrypt.encrypt(data)
    return result
  },
  /* 加密 */
  encrypt(data) {
    
    
    const PUBLIC_KEY = publicKey
    var encryptor = new Encrypt()
    encryptor.setPublicKey(PUBLIC_KEY)
    // 如果是对象/数组的话,需要先JSON.stringify转换成字符串
    const result = encryptor.encryptLong(data)
    return result
  },
  /* 解密 - PRIVATE_KEY - 验证 */
  decrypt(data) {
    
    
    const PRIVATE_KEY = privateKey
    var encryptor = new Encrypt()
    encryptor.setPrivateKey(PRIVATE_KEY)
    // 如果是对象/数组的话,需要先JSON.stringify转换成字符串
    var result = encryptor.decryptLong(data)
    return result
  }
}

4. Global references

import Rsa from "@/utils/rsa.js"
Vue.prototype.Rsa = Rsa //

5. Use RSA to add solution on *.vue page, use it globally

this.Rsa.方法名 

Reference front-end implementation

2.2, the backend implements rsa decryption

1. Introduce hutool dependency



<!-- 工具类 参考https://hutool.cn/docs-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.3.10</version>
        </dependency>

2. Method

private String decodeStr(String encodeStr) {
    
    
        try {
    
    
            String privateKey = ResourceUtil.readUtf8Str(PRIVATE_KEY_LOCATION);
            RSA rsa = new RSA(privateKey, null);
            byte[] aByte = SecureUtil.decode(encodeStr);
            byte[] decrypt = rsa.decrypt(aByte, KeyType.PrivateKey);
            return StrUtil.str(decrypt, CharsetUtil.CHARSET_UTF_8);
        } catch (Exception e) {
    
    
            logger.error("RSA私钥解密失败!", e);
            throw new BadCredentialsException(encodeStr);
        }
    }

3. For hutool encryption and decryption use refer to
hutools address
insert image description here

3. AES encryption front-end and back-end implementation

3.1, AES front-end implementation

1. Download dependencies

 下载crypto-js
npm install crypto-js --save

2. The specific use of the code

import CryptoJS from 'crypto-js'

const key = 'f4k9f5w7f8g4er26' //前后端使用同意秘钥
// 偏移量 16位(不可随意修改,否则前后端加密解密可能失败)
const iv = '0000000000000000'

export function encrypt(data) {
    
    
  return CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(data), CryptoJS.enc.Utf8.parse(key), {
    
    
    iv: CryptoJS.enc.Utf8.parse(iv),
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7
  })
    .toString()
}
export function decrypt(data) {
    
    
  const decrypted = CryptoJS.AES.decrypt(data, CryptoJS.enc.Utf8.parse(key), {
    
    
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7
  })
  return decrypted.toString(CryptoJS.enc.Utf8).toString()
}

3. The global reference is the same as above rsa

3.2. Implementation of AES backend decryption (2 methods)

1. Use hutool tools (it is relatively more convenient to use hutool)
insert image description here

String content = "test中文";

//随机生成密钥
byte[] key = SecureUtil.generateKey(SymmetricAlgorithm.AES.getValue()).getEncoded();

//构建
SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key);

//加密
byte[] encrypt = aes.encrypt(content);
//解密
byte[] decrypt = aes.decrypt(encrypt);

//加密为16进制表示
String encryptHex = aes.encryptHex(content);
//解密为字符串
String decryptStr = aes.decryptStr(encryptHex, CharsetUtil.CHARSET_UTF_8);

2. Use commons-code dependent tools
to introduce dependencies

<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.15</version>
</dependency>

aes tools

public class Encrypt {
    
    

    //--------------AES---------------
    private static final String KEY = "f4k9f5w7f8g4er26";  // 密匙,必须16位
    private static final String ENCODING = "UTF-8"; // 编码
    private static final String ALGORITHM = "AES"; //算法
    private static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding"; // 默认的加密算法,ECB模式

    /**
     *  AES加密
     * @param data
     * @return String
     */
    public static String AESencrypt(String data) throws Exception
    {
    
    
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        kgen.init(128);
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE,new SecretKeySpec(KEY.getBytes(),"AES"));
        byte[] b = cipher.doFinal(data.getBytes("utf-8"));
        //采用base64算法进行转码,避免出现中文乱码
        return Base64.encodeBase64String(b);
    }

    /**
     * AES解密
     * @param data
     * @return String
     */
    public static String AESdecrypt(String data) throws Exception {
    
    
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        kgen.init(128);
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(KEY.getBytes(), "AES"));
        byte[] b = cipher.doFinal(Base64.decodeBase64(data));
        //采用base64算法进行转码,避免出现中文乱码
        return new String(b);
    }
    public static void main(String[] args) throws Exception {
    
    
        String mi = Encrypt.AESencrypt("111111");
        System.out.println(mi);
    }

}

Guess you like

Origin blog.csdn.net/wei1359765074410/article/details/127786653