[Java tools] Symmetric encryption integration AES, DES algorithm encryption and decryption tools

  • The symmetric encryption algorithm is just to distinguish asymmetric encryption algorithms. The characteristic is 加密是加密解密使用相同的密钥that asymmetric encryption 加密和解密时使用的密钥不一样.
    • Asymmetric encryption can be used in the key exchange of symmetric encryption, which effectively protects the security of the key.
    • Asymmetric encryption encryption and decryption keys are different, and the security is high, but the encryption and decryption speed is very slow, which is not suitable for big data encryption. The symmetric encryption is fast, so it is best to use it in combination.

Commonly used symmetric encryption algorithms are: AES and DES.

  • DES: 比较老的算法There are three parameter entries (original text, key, encryption mode). 3DES is just a mode of DES, a more secure variant based on DES, which encrypts data three times and is also designated as a transitional algorithm of AES.
  • AES : Advanced Encryption Standard, a new generation standard,加密速度更快,安全性更高(优先选择)
import org.junit.Test;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Base64;

public class SymmetricEncryptionUtil {
    
    
    private static final String AES = "AES";
    private static final String DES = "DES";
    /**
     * AES密钥
     */
    private static final String AES_KEY = "FFC22E80F61AB7295C02493856B4C520";

    /**
     * AES模式
     */
    private static final String AES_MODE = "AES/ECB/PKCS5Padding";


    /**
     * DES密钥: 加解密用到的秘钥-getBytes().length即字节的长度必须大于等于8,否则报异常java.security.InvalidKeyException: Wrong key size
     */
    private static final String DES_KEY = "*%#@()^&";
    /**
     * DES模式
     * "AES/ECB/PKCS5Padding"在加密和解密时必须相同,可以直接写”AES”,这样就是使用默认模式分别的意思为:AES是加密算法,ECB是工作模式,PKCS5Padding是填充方式。
     */
    private static final String DES_MODE = "DES/ECB/PKCS5Padding";


    /**
     * 使用AES对字符串加密
     *
     * @param str utf8编码的字符串
     * @param key 密钥(16字节)
     * @return 加密结果
     * @throws Exception
     */
    public static String aesEncrypt(String str, String key) throws Exception {
    
    
        if (str == null || key == null) {
    
    
            return null;
        }

        //AES/ECB/PKCS5Padding在加密和解密时必须相同
        Cipher cipher = Cipher.getInstance(AES_MODE);
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), AES));
        byte[] bytes = cipher.doFinal(str.getBytes(StandardCharsets.UTF_8));

        //使用base64编码
        return Base64.getEncoder().encodeToString(bytes);
    }

    /**
     * 使用AES对数据解密
     *
     * @param base64Encoder base64编码后的字符串
     * @param key           密钥(16字节)
     * @return 解密结果
     * @throws Exception
     */
    public static String aesDecrypt(String base64Encoder, String key) throws Exception {
    
    
        if (base64Encoder == null || key == null) {
    
    
            return null;
        }

        SecureRandom random = new SecureRandom();
        Cipher cipher = Cipher.getInstance(AES_MODE);
        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), AES), random);

        //使用base64解码
        byte[] base64DecoderByte = Base64.getDecoder().decode(base64Encoder);
        return new String(cipher.doFinal(base64DecoderByte), StandardCharsets.UTF_8);
    }


    /**
     * 使用DES对字符串加密
     *
     * @param str utf8编码的字符串
     * @param key 密钥(56位,7字节)
     * @return 加密结果
     * @throws Exception
     */
    public static String desEncrypt(String str, String key) throws Exception {
    
    
        if (str == null || key == null) {
    
    
            return null;
        }

        SecureRandom random = new SecureRandom();
        Cipher cipher = Cipher.getInstance(DES_MODE);
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), DES), random);
        byte[] bytes = cipher.doFinal(str.getBytes(StandardCharsets.UTF_8));

        //使用base64编码
        return Base64.getEncoder().encodeToString(bytes);
    }

    /**
     * 使用DES对数据解密
     *
     * @param base64Encoder base64编码后的字符串
     * @param key           密钥(16字节)
     * @return 解密结果
     * @throws Exception
     */
    public static String desDecrypt(String base64Encoder, String key) throws Exception {
    
    
        if (base64Encoder == null || key == null) {
    
    
            return null;
        }
        Cipher cipher = Cipher.getInstance(DES_MODE);
        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), DES));
        //使用base64解码
        byte[] base64DecoderByte = Base64.getDecoder().decode(base64Encoder);

        return new String(cipher.doFinal(base64DecoderByte), StandardCharsets.UTF_8);
    }


    /**
     * 测试AES算法
     *
     * @throws Exception
     */
    @Test
    public void main1() throws Exception {
    
    
        String str = "你好,张三!";
        System.out.println("原文:" + str);
        System.out.println("密钥:" + AES_KEY);

        String aesEncrypt = aesEncrypt(str, AES_KEY);
        System.out.println("加密后:" + aesEncrypt);

        String aesDecrypt = aesDecrypt(aesEncrypt, AES_KEY);
        System.out.println("解密后:" + aesDecrypt);
    }


    /**
     * 测试DES算法
     *
     * @throws Exception
     */
    @Test
    public void main2() throws Exception {
    
    
        String str = "你好,张三!";
        System.out.println("原文:" + str);
        System.out.println("密钥:" + DES_KEY);

        String aesEncrypt = desEncrypt(str, DES_KEY);
        System.out.println("加密后:" + aesEncrypt);

        String aesDecrypt = desDecrypt(aesEncrypt, DES_KEY);
        System.out.println("解密后:" + aesDecrypt);
    }
}

执行结果

```java
//main1
原文:你好,张三!
密钥:FFC22E80F61AB7295C02493856B4C520
加密后:Vlm7AY5VxhiOc5QSZe5Szga2oN2+AMpMDyHU9tYktFw=
解密后:你好,张三!

//main2
原文:你好,张三!
密钥:*%#@()^&
加密后:STDcjuovhcYOwV/tFmrvPH25wWw6o48M
解密后:你好,张三!

All parameters of the AES algorithm are bytecode (including the key). Therefore, the string characters need to be encrypted after being converted into bytecode

  • Parameters: ”AES/ECB/PKCS5Padding”in must be the same encryption and decryption , you can write directly "AES", this is the default mode. The meaning of each is: AES is 加密算法, ECB is 工作模式, PKCS5Padding is 填充方式.

AES is a block encryption algorithm, also known as block encryption. Each group is 16 bytes. This way the plaintext will be divided into multiple pieces. When there is a block less than 16 bytes, it will be filled. There are four working modes:

  • ECB electronic codebook mode : The same plaintext block produces the same ciphertext block, which is easy to operate in parallel, but it is also possible to attack the plaintext.
  • CBC Encrypted Packet Link Mode : A block of plaintext is encrypted and linked with the previous block of ciphertext, which is not conducive to parallelism, but the security is better than ECB, and it is the standard of SSL and IPSec.
  • CFB encryption feedback mode : Calculate the last ciphertext with the key, and then encrypt it. Hiding the plaintext mode is not conducive to parallelism and error transmission.
  • OFB output feedback mode : Calculate the key processed last time with the key, and then encrypt it. Hiding the plaintext mode is not conducive to parallelism, and may cause plaintext attacks and error transmission.

The padding method of PKCS5Padding is to fill in the number as much as the difference in bytes; when each is less than 16 bytes, then a set of padding will be added to 16. There are other padding modes [Nopadding, ISO10126Padding] (does not affect the algorithm, encryption and decryption Time is consistent).

Guess you like

Origin blog.csdn.net/qq877728715/article/details/115214433