铁马冰河2000

导航

Java加解密-AES对称加密算法

AES

  AES产生的原因是3重DES的效率比较低而DES的安全性较低。AES是目前使用最多的对称加密算法,AES还有一个优势是至今尚未被破解。AES通常用于移动通信系统的加密以及基于SSH协议的软件(SSH Client、SecurityCRT)的加密。密钥长度以及实现方如下:

  无政策限制权限文件是指:因为某些国家的进口管制限制,java发布的运行环境包中的一些加解密有一定的限制(因为美国政府的一些原因)。一般的JDK的jre的security包中的local_policy.jar和US_export_policy.jar都是没有内容的,所以只能使用128位加密。下面是JDK和BC实现的AES加密(步骤和DES类似):

============================================================================AES加解密工具类:

import java.security.Key;
import java.security.SecureRandom;
import java.security.Security;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class SecurityAES {
    
    public static String AES_MODE_JDK = "jdk";
    public static String AES_MODE_BC = "bouncyCastle";
    private Key key;
    
    //单例模式
    private static SecurityAES securityAES;
    public static SecurityAES getInstance(String password, String succurityMode) {
        if(securityAES == null) {
            securityAES = new SecurityAES(password, succurityMode);
        }
        return securityAES;
    }
    
    private SecurityAES(String password, String succurityMode)  {
        try{
            //1.生成key
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            secureRandom.setSeed(password.getBytes());
            KeyGenerator keyGenerator;
            if(StringUtils.isNotBlank(succurityMode) && StringUtils.equals(AES_MODE_BC, succurityMode)) {
                 Security.addProvider(new BouncyCastleProvider());
                 keyGenerator = KeyGenerator.getInstance("aes", "BC");
            }else {
                keyGenerator = KeyGenerator.getInstance("aes");
            }
            keyGenerator.init(128, secureRandom);//初始化key的长度,只能是128,
            SecretKey secretKey = keyGenerator.generateKey();//生成key
            byte[] keyBytes = secretKey.getEncoded();//得到key的字节数组
            //2.key的转换
            key = new SecretKeySpec(keyBytes, "aes");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public byte[] encrypt(byte[] array) {
        try{
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");//加解密方式+工作模式+填充方式
            cipher.init(Cipher.ENCRYPT_MODE, key);//以加密模式初始化
            return cipher.doFinal(array);
        } catch(Exception e ){
            e.printStackTrace();
        }
        return null;
    }
    
    public byte[] decrypt(byte[] array) {
        try{
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");//加解密方式+工作模式+填充方式
            cipher.init(Cipher.DECRYPT_MODE, key);
            return cipher.doFinal(array);
        } catch(Exception e ){
            e.printStackTrace();
        }
        return null;
    }
}

============================================================================AES加解密工具测试类:

    @Test
    public void test_AES() throws Exception {
        String src = "面向对象编程,object-oriented!@#*5"; // 需要加密的原始字符串
        String password = "123456";
        SecurityAES securityJdkAES = SecurityAES.getInstance(password, SecurityAES.AES_MODE_JDK);
        byte[] encodeJdkAES = securityJdkAES.encrypt(src.getBytes());
        System.out.println("JDK AES加密:" + Base64.encodeBase64String(encodeJdkAES));
        byte[] decodeJdkAES = securityJdkAES.decrypt(encodeJdkAES);
        System.out.println("JDK AES解密:" + new String(decodeJdkAES));
        
        SecurityAES securityBcAES = SecurityAES.getInstance(password, SecurityAES.AES_MODE_BC);
        byte[] encodeBcAES = securityBcAES.encrypt(src.getBytes());
        System.out.println("bouncyCastle AES加密:" + Base64.encodeBase64String(encodeBcAES));
        byte[] decodeBcAES = securityBcAES.decrypt(encodeBcAES);
        System.out.println("bouncyCastle AES解密:" + new String(decodeBcAES));
    }

 

posted on 2022-01-23 22:33  铁马冰河2000  阅读(699)  评论(0编辑  收藏  举报