code
package com.xcg.webapp.common;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
/**
 * 加密/解密
 * */
public class EncryptUtil {
    /**
     * @param text           明文/base64密文
     * @param key            密钥 AES必须16字节/DES必须8字节/TripleDES必须24字节
     * @param transformation 转换方式 AES/DES
     * @param mode           加密/解密
     */
    public static String extracted(String text, String key, String transformation, boolean mode) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        Cipher cipher = Cipher.getInstance(transformation);
        //key与给定的密钥内容相关联的密钥算法的名称
        SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), transformation);
        //Cipher 的操作模式,加密模式:ENCRYPT_MODE、 解密模式:DECRYPT_MODE、包装模式:WRAP_MODE 或 解包装:UNWRAP_MODE)
        cipher.init(mode ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, secretKeySpec);
        byte[] bytes = cipher.doFinal(mode ? text.getBytes(StandardCharsets.UTF_8) : Base64.getDecoder().decode(text));
        return mode ? new String(Base64.getEncoder().encode(bytes)) : new String(bytes);
    }
//    原文链接:https://blog.csdn.net/qq_51534884/article/details/130361254

    public static String encrypt(String key, String plaintext) {
        try {
            byte[] keyBytes = key.getBytes();
            SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            byte[] iv = cipher.getParameters().getParameterSpec(IvParameterSpec.class).getIV();
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(iv));
            byte[] ciphertext = cipher.doFinal(plaintext.getBytes());
            return Base64.getEncoder().encodeToString(iv) + ":" + Base64.getEncoder().encodeToString(ciphertext);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static String decrypt(String key, String ciphertext) {
        try {
            byte[] keyBytes = key.getBytes();
            String[] parts = ciphertext.split(":");
            byte[] iv = Base64.getDecoder().decode(parts[0]);
            byte[] encrypted = Base64.getDecoder().decode(parts[1]);
            SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(iv));
            byte[] plaintext = cipher.doFinal(encrypted);
            return new String(plaintext);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
//    原文链接:https://cloud.tencent.com/developer/information/%E7%94%A8Java%E5%8A%A0%E5%AF%86%E5%92%8C%E8%A7%A3%E5%AF%86%E5%AF%86%E7%A0%81
}

String text = "你好世界!!";
        String key = "12345678";//des必须8字节
        // 算法/模式/填充  默认 DES/ECB/PKCS5Padding
        String transformation = "DES";

        String key1 = "abcd56781234abcd";//aes必须16字节
        String transformation1 = "AES";

        String key2 = "123456781234567812345678";//TripleDES使用24字节的key
        String transformation2 = "TripleDes";

//        String extractedStr = AESDESUtil.extracted(text, key1, transformation1, true);
//        System.out.println("AES加密:" + extractedStr);
//        String extractedStr1 = AESDESUtil.extracted(extractedStr, key1, transformation1, false);
//        System.out.println("解密:" + extractedStr1);
//        原文链接:https://blog.csdn.net/qq_51534884/article/details/130361254

        String extractedStr = EncryptUtil.encrypt(key1, text);
        System.out.println("AES加密:" + extractedStr);
        String extractedStr1 = EncryptUtil.decrypt(key1, extractedStr);
        System.out.println("AES解密:" + extractedStr1);

 
使用AES/GCM/NoPadding方式更安全,把iv放在密文前面,用///分隔开,每次解密时先把iv取出,然后再解密。加密和解密要用相同的key和iv,否则没法解密。
秘钥必须16位。如果是Java中,则需要把IvParameterSpec ivSpec = new IvParameterSpec(iv);替换为:GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, iv);

/**
     * 加密
     * */
    public static String extractedForEncryption(String text) throws Exception {
        //Cipher 的操作模式,加密模式:ENCRYPT_MODE、 解密模式:DECRYPT_MODE、包装模式:WRAP_MODE 或 解包装:UNWRAP_MODE)
        int encryptMode = Cipher.ENCRYPT_MODE;
        // GCM模式需要12或16字节的IV
        byte[] iv = new byte[16];
        // 生成随机IV
        new SecureRandom().nextBytes(iv);
        String ivStr = new String(android.util.Base64.encode(iv, Base64.NO_WRAP));

        // 创建IV参数规范
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
        // 创建密钥规范 key与给定的密钥内容相关联的密钥算法的名称。
        SecretKeySpec keySpec = new SecretKeySpec(gd.AESSecretKey().getBytes(), "AES");
        // 获取Cipher实例
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
        // 初始化Cipher实例,传入IV
        cipher.init(encryptMode, keySpec, ivSpec);

        byte[] enBytes = text.getBytes(StandardCharsets.UTF_8);
        byte[] bytes = cipher.doFinal(enBytes);

        String res = new String(android.util.Base64.encode(bytes, Base64.NO_WRAP));
        res = ivStr + "///" + res;
        return res;
    }

    /**
     * 解密
     * */
    public static String extractedForDecryption(String text) throws Exception {
        //Cipher 的操作模式,加密模式:ENCRYPT_MODE、 解密模式:DECRYPT_MODE、包装模式:WRAP_MODE 或 解包装:UNWRAP_MODE)
        int encryptMode = Cipher.DECRYPT_MODE;
        String[] arr = text.split("///");
        //iv字符串
        String ivStr = arr[0];
        //密文字符串
        String conStr = arr[1];
        byte[] iv = android.util.Base64.decode(ivStr, Base64.NO_WRAP);
        // 创建IV参数规范
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
        // 创建密钥规范 key与给定的密钥内容相关联的密钥算法的名称。
        SecretKeySpec keySpec = new SecretKeySpec(gd.AESSecretKey().getBytes(), "AES");
        // 获取Cipher实例
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
        // 初始化Cipher实例,传入IV
        cipher.init(encryptMode, keySpec, ivSpec);
        //密文转bytes
        byte[] deBytes = android.util.Base64.decode(conStr, Base64.NO_WRAP);
        //解密
        byte[] bytes = cipher.doFinal(deBytes);
        //解密字符串
        String res = new String(bytes);
        return res;
    }

 

posted on 2024-09-09 14:48  邢帅杰  阅读(34)  评论(0)    收藏  举报