[Herramientas de Java] Integración de cifrado simétrico Herramientas de cifrado y descifrado de algoritmo AES, DES

  • El algoritmo de cifrado simétrico es solo para distinguir los algoritmos de cifrado asimétrico. La característica es 加密是加密解密使用相同的密钥ese cifrado asimétrico 加密和解密时使用的密钥不一样.
    • El cifrado asimétrico se puede utilizar en el intercambio de claves de cifrado simétrico, que protege eficazmente la seguridad de la clave.
    • Las claves de cifrado y descifrado de cifrado asimétrico son diferentes, y la seguridad es alta, pero la velocidad de cifrado y descifrado es muy lenta, lo que no es adecuado para el cifrado de big data. El cifrado simétrico es rápido, por lo que es mejor usarlo en combinación.

Los algoritmos de cifrado simétrico más utilizados son: AES y DES.

  • DES: 比较老的算法Hay tres entradas de parámetros (texto original, clave, modo de encriptación). 3DES es solo un modo de DES, una variante más segura basada en DES, que cifra los datos tres veces y también se designa como un algoritmo de transición de AES.
  • AES : Advanced Encryption Standard, un estándar de nueva generación,加密速度更快,安全性更高(优先选择)
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
解密后:你好,张三!

Todos los parámetros del algoritmo AES son bytecode (incluida la clave). Por lo tanto, los caracteres de la cadena deben cifrarse después de convertirse en código de bytes.

  • Parámetros: ”AES/ECB/PKCS5Padding”en que debe ser el mismo cifrado y descifrado , se puede escribir directamente "AES", este es el modo por defecto. El significado de cada uno es: AES es 加密算法, ECB es 工作模式, PKCS5Padding es 填充方式.

AES es un algoritmo de cifrado de bloques, también conocido como cifrado de bloques. Cada grupo tiene 16 bytes. De esta forma, el texto sin formato se dividirá en varias partes. Cuando hay un bloque de menos de 16 bytes, se llenará. Hay cuatro modos de trabajo:

  • Modo de libro de códigos electrónico ECB : el mismo bloque de texto sin formato produce el mismo bloque de texto cifrado, que es fácil de operar en paralelo, pero también es posible atacar el texto sin formato.
  • Modo de enlace de paquete cifrado CBC : un bloque de texto sin formato se cifra y se vincula con el bloque anterior de texto cifrado, lo que no favorece el paralelismo, pero la seguridad es mejor que ECB, que es el estándar de SSL e IPSec.
  • Modo de retroalimentación de cifrado CFB : Calcule el último texto cifrado con la clave y luego cifre. Ocultar el modo de texto sin formato no conduce al paralelismo ni a la transmisión de errores.
  • Modo de retroalimentación de salida OFB : calcula la clave procesada la última vez con la clave y luego encripta. Ocultar el modo de texto sin formato no favorece el paralelismo y puede provocar ataques de texto sin formato y transmisión de errores.

El método de relleno de PKCS5Padding es completar el número tanto como la diferencia en bytes; cuando cada uno tiene menos de 16 bytes, se agregará un conjunto de relleno a 16. Hay otros modos de relleno [Nopadding, ISO10126Padding] (no no afecta el algoritmo, el tiempo de cifrado y descifrado es consistente).

Supongo que te gusta

Origin blog.csdn.net/qq877728715/article/details/115214433
Recomendado
Clasificación