JAVA 实现AES加密的两种方法

写在前面的话:
    1.建议加密后将密文转为16进制的字符串(便于观看)。

    2.以下的两种加密的方法密钥不限定长度。

  1. /** 
  2.  *AES加密解密工具类 
  3.  *@author M-Y 
  4.  */  
  5. public class AESUtil {  
  6.       private static final Logger logger = Logger.getLogger(AESUtil.class);  
  7.       private static final String defaultCharset = "UTF-8";  
  8.       private static final String KEY_AES = "AES";  
  9.       private static final String KEY = "123456";  
  10.     /** 
  11.      * 加密 
  12.      * 
  13.      * @param data 需要加密的内容 
  14.      * @param key 加密密码 
  15.      * @return 
  16.      */  
  17.     public static String encrypt(String data, String key) {  
  18.         return doAES(data, key, Cipher.ENCRYPT_MODE);  
  19.     }  
  20.   
  21.     /** 
  22.      * 解密 
  23.      * 
  24.      * @param data 待解密内容 
  25.      * @param key 解密密钥 
  26.      * @return 
  27.      */  
  28.     public static String decrypt(String data, String key) {  
  29.         return doAES(data, key, Cipher.DECRYPT_MODE);  
  30.     }  
  31.   
  32.     /** 
  33.      * 加解密 
  34.      * 
  35.      * @param data 待处理数据 
  36.      * @param password  密钥 
  37.      * @param mode 加解密mode 
  38.      * @return 
  39.      */  
  40.     private static String doAES(String data, String key, int mode) {  
  41.         try {  
  42.             if (StringUtils.isBlank(data) || StringUtils.isBlank(key)) {  
  43.                 return null;  
  44.             }  
  45.             //判断是加密还是解密  
  46.             boolean encrypt = mode == Cipher.ENCRYPT_MODE;  
  47.             byte[] content;  
  48.             //true 加密内容 false 解密内容  
  49.             if (encrypt) {  
  50.                 content = data.getBytes(defaultCharset);  
  51.             } else {  
  52.                 content = parseHexStr2Byte(data);  
  53.             }  
  54.             //1.构造密钥生成器,指定为AES算法,不区分大小写  
  55.             KeyGenerator kgen = KeyGenerator.getInstance(KEY_AES);  
  56.             //2.根据ecnodeRules规则初始化密钥生成器  
  57.             //生成一个128位的随机源,根据传入的字节数组  
  58.             kgen.init(128new SecureRandom(key.getBytes()));  
  59.             //3.产生原始对称密钥  
  60.             SecretKey secretKey = kgen.generateKey();  
  61.             //4.获得原始对称密钥的字节数组  
  62.             byte[] enCodeFormat = secretKey.getEncoded();  
  63.             //5.根据字节数组生成AES密钥  
  64.             SecretKeySpec keySpec = new SecretKeySpec(enCodeFormat, KEY_AES);  
  65.             //6.根据指定算法AES自成密码器  
  66.             Cipher cipher = Cipher.getInstance(KEY_AES);// 创建密码器  
  67.             //7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作,第二个参数为使用的KEY  
  68.             cipher.init(mode, keySpec);// 初始化  
  69.             byte[] result = cipher.doFinal(content);  
  70.             if (encrypt) {  
  71.                 //将二进制转换成16进制  
  72.                 return parseByte2HexStr(result);  
  73.             } else {  
  74.                 return new String(result, defaultCharset);  
  75.             }  
  76.         } catch (Exception e) {  
  77.             logger.error("AES 密文处理异常", e);  
  78.         }  
  79.         return null;  
  80.     }  
  81.     /** 
  82.      * 将二进制转换成16进制 
  83.      * 
  84.      * @param buf 
  85.      * @return 
  86.      */  
  87.     public static String parseByte2HexStr(byte buf[]) {  
  88.         StringBuilder sb = new StringBuilder();  
  89.         for (int i = 0; i < buf.length; i++) {  
  90.             String hex = Integer.toHexString(buf[i] & 0xFF);  
  91.             if (hex.length() == 1) {  
  92.                 hex = '0' + hex;  
  93.             }  
  94.             sb.append(hex.toUpperCase());  
  95.         }  
  96.         return sb.toString();  
  97.     }  
  98.     /** 
  99.      * 将16进制转换为二进制 
  100.      * 
  101.      * @param hexStr 
  102.      * @return 
  103.      */  
  104.     public static byte[] parseHexStr2Byte(String hexStr) {  
  105.         if (hexStr.length() < 1) {  
  106.             return null;  
  107.         }  
  108.         byte[] result = new byte[hexStr.length() / 2];  
  109.         for (int i = 0; i < hexStr.length() / 2; i++) {  
  110.             int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);  
  111.             int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);  
  112.             result[i] = (byte) (high * 16 + low);  
  113.         }  
  114.         return result;  
  115.     }  
  116.     public static void main(String[] args) throws Exception {    
  117.         String content = "{'repairPhone':'18547854787','customPhone':'12365478965','captchav':'58m7'}";    
  118.         System.out.println("加密前:" + content);    
  119.         System.out.println("加密密钥和解密密钥:" + KEY);    
  120.         String encrypt = encrypt(content, KEY);    
  121.         System.out.println("加密后:" + encrypt);    
  122.         String decrypt = decrypt(encrypt, KEY);    
  123.         System.out.println("解密后:" + decrypt);    
  124.     }    
  125. }  
/**
 *AES加密解密工具类
 *@author M-Y
 */
public class AESUtil {
      private static final Logger logger = Logger.getLogger(AESUtil.class);
      private static final String defaultCharset = "UTF-8";
      private static final String KEY_AES = "AES";
      private static final String KEY = "123456";
    /**
     * 加密
     *
     * @param data 需要加密的内容
     * @param key 加密密码
     * @return
     */
    public static String encrypt(String data, String key) {
        return doAES(data, key, Cipher.ENCRYPT_MODE);
    }

    /**
     * 解密
     *
     * @param data 待解密内容
     * @param key 解密密钥
     * @return
     */
    public static String decrypt(String data, String key) {
        return doAES(data, key, Cipher.DECRYPT_MODE);
    }

    /**
     * 加解密
     *
     * @param data 待处理数据
     * @param password  密钥
     * @param mode 加解密mode
     * @return
     */
    private static String doAES(String data, String key, int mode) {
        try {
            if (StringUtils.isBlank(data) || StringUtils.isBlank(key)) {
                return null;
            }
            //判断是加密还是解密
            boolean encrypt = mode == Cipher.ENCRYPT_MODE;
            byte[] content;
            //true 加密内容 false 解密内容
            if (encrypt) {
                content = data.getBytes(defaultCharset);
            } else {
                content = parseHexStr2Byte(data);
            }
            //1.构造密钥生成器,指定为AES算法,不区分大小写
            KeyGenerator kgen = KeyGenerator.getInstance(KEY_AES);
            //2.根据ecnodeRules规则初始化密钥生成器
            //生成一个128位的随机源,根据传入的字节数组
            kgen.init(128, new SecureRandom(key.getBytes()));
            //3.产生原始对称密钥
            SecretKey secretKey = kgen.generateKey();
            //4.获得原始对称密钥的字节数组
            byte[] enCodeFormat = secretKey.getEncoded();
            //5.根据字节数组生成AES密钥
            SecretKeySpec keySpec = new SecretKeySpec(enCodeFormat, KEY_AES);
            //6.根据指定算法AES自成密码器
            Cipher cipher = Cipher.getInstance(KEY_AES);// 创建密码器
            //7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作,第二个参数为使用的KEY
            cipher.init(mode, keySpec);// 初始化
            byte[] result = cipher.doFinal(content);
            if (encrypt) {
                //将二进制转换成16进制
                return parseByte2HexStr(result);
            } else {
                return new String(result, defaultCharset);
            }
        } catch (Exception e) {
            logger.error("AES 密文处理异常", e);
        }
        return null;
    }
    /**
     * 将二进制转换成16进制
     *
     * @param buf
     * @return
     */
    public static String parseByte2HexStr(byte buf[]) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < buf.length; i++) {
            String hex = Integer.toHexString(buf[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            sb.append(hex.toUpperCase());
        }
        return sb.toString();
    }
    /**
     * 将16进制转换为二进制
     *
     * @param hexStr
     * @return
     */
    public static byte[] parseHexStr2Byte(String hexStr) {
        if (hexStr.length() < 1) {
            return null;
        }
        byte[] result = new byte[hexStr.length() / 2];
        for (int i = 0; i < hexStr.length() / 2; i++) {
            int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
            int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
            result[i] = (byte) (high * 16 + low);
        }
        return result;
    }
    public static void main(String[] args) throws Exception {  
        String content = "{'repairPhone':'18547854787','customPhone':'12365478965','captchav':'58m7'}";  
        System.out.println("加密前:" + content);  
        System.out.println("加密密钥和解密密钥:" + KEY);  
        String encrypt = encrypt(content, KEY);  
        System.out.println("加密后:" + encrypt);  
        String decrypt = decrypt(encrypt, KEY);  
        System.out.println("解密后:" + decrypt);  
    }  
}
输出结果:
  1. 加密前:{'repairPhone':'18547854787','customPhone':'12365478965','captchav':'58m7'}  
  2. 加密密钥和解密密钥:123456  
  3. 加密后:2A3D75862E69BF61DFAD94017E930227A715C8E533AA1A12361D6BE6E190EC5EE77AA66CAC8005A643BFB26134EE60398C30104B1F7FB3CC6B78795368A86D8215B88A5C80D9C2E4936EEEB0DECA7A88  
  4. 解密后:{'repairPhone':'18547854787','customPhone':'12365478965','captchav':'58m7'}  
加密前:{'repairPhone':'18547854787','customPhone':'12365478965','captchav':'58m7'}
加密密钥和解密密钥:123456
加密后:2A3D75862E69BF61DFAD94017E930227A715C8E533AA1A12361D6BE6E190EC5EE77AA66CAC8005A643BFB26134EE60398C30104B1F7FB3CC6B78795368A86D8215B88A5C80D9C2E4936EEEB0DECA7A88
解密后:{'repairPhone':'18547854787','customPhone':'12365478965','captchav':'58m7'}
方法二:替换AESUtil 类中的doAES方法并加上以下成员

  1. private static final String KEY_MD5 = "MD5";  
  2. private static MessageDigest md5Digest;  
  3.   
  4. static {  
  5.     try {  
  6.         md5Digest = MessageDigest.getInstance(KEY_MD5);  
  7.     } catch (NoSuchAlgorithmException e) {  
  8.         //  
  9.     }  
  10. }  
    private static final String KEY_MD5 = "MD5";
    private static MessageDigest md5Digest;

    static {
        try {
            md5Digest = MessageDigest.getInstance(KEY_MD5);
        } catch (NoSuchAlgorithmException e) {
            //
        }
    }
doAES方法:

  1. /** 
  2.      * 加解密 
  3.      * 
  4.      * @param data 
  5.      * @param key 
  6.      * @param mode 
  7.      * @return 
  8.      */  
  9.     private static String doAES(String data, String key, int mode) {  
  10.         try {  
  11.             if (StringUtils.isBlank(data) || StringUtils.isBlank(key)) {  
  12.                 return null;  
  13.             }  
  14.             boolean encrypt = mode == Cipher.ENCRYPT_MODE;  
  15.             byte[] content;  
  16.             //true 加密内容 false 解密内容  
  17.             if (encrypt) {  
  18.                 content = data.getBytes(defaultCharset);  
  19.             } else {  
  20.                  content = parseHexStr2Byte(data);  
  21.             }  
  22.             SecretKeySpec keySpec = new SecretKeySpec(md5Digest.digest(key.getBytes(defaultCharset)), KEY_AES);//构造一个密钥  
  23.             Cipher cipher = Cipher.getInstance(KEY_AES);// 创建密码器  
  24.             cipher.init(mode, keySpec);// 初始化  
  25.             byte[] result = cipher.doFinal(content);//加密或解密  
  26.             if (encrypt) {  
  27.                 return parseByte2HexStr(result);  
  28.             } else {  
  29.                 return new String(result, defaultCharset);  
  30.             }  
  31.         } catch (Exception e) {  
  32.             logger.error("AES 密文处理异常", e);  
  33.         }  
  34.         return null;  
  35.     }  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C# 和 Java 都支持 AES 加密算法,因此可以在两种语言中进行加密和解密。下面是一个示例代码,演示了 C# 和 Java 中如何使用 AES 加密和解密数据。 首先是 Java 中的代码,用于加密数据: ```java import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; public class AesEncryption { private static final String ALGORITHM = "AES/CBC/PKCS5Padding"; private static final String KEY = "0123456789abcdef"; // 16-byte key private static final String IV = "0123456789abcdef"; // 16-byte initialization vector public static String encrypt(String data) throws Exception { Cipher cipher = Cipher.getInstance(ALGORITHM); SecretKeySpec keySpec = new SecretKeySpec(KEY.getBytes(), "AES"); IvParameterSpec ivSpec = new IvParameterSpec(IV.getBytes()); cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); byte[] encrypted = cipher.doFinal(data.getBytes()); return Base64.getEncoder().encodeToString(encrypted); } } ``` 这个代码使用了 AES/CBC/PKCS5Padding 加密算法,采用了 16 字节的密钥和初始化向量。`encrypt()` 方法接受一个字符串参数,并返回加密后的字符串。 接下来是 C# 中的代码,用于解密数据: ```csharp using System; using System.Security.Cryptography; using System.Text; public class AesDecryption { private static readonly byte[] Key = Encoding.UTF8.GetBytes("0123456789abcdef"); // 16-byte key private static readonly byte[] Iv = Encoding.UTF8.GetBytes("0123456789abcdef"); // 16-byte initialization vector public static string Decrypt(string data) { byte[] encryptedData = Convert.FromBase64String(data); using (Aes aes = Aes.Create()) { aes.Key = Key; aes.IV = Iv; aes.Padding = PaddingMode.PKCS7; aes.Mode = CipherMode.CBC; ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV); byte[] decrypted = decryptor.TransformFinalBlock(encryptedData, 0, encryptedData.Length); return Encoding.UTF8.GetString(decrypted); } } } ``` 这个代码使用了相同的 AES/CBC/PKCS5Padding 加密算法和 16 字节的密钥和初始化向量。`Decrypt()` 方法接受一个加密的字符串参数,并返回解密后的字符串。 使用这两个类,可以在 C# 和 Java 中进行 AES 加密和解密操作。注意,密钥和初始化向量需要在两种语言中保持一致。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值