AES加解密Util

public class ByteUtil {
	
	/**
	 * 将byte数组报文(根据ASCII码值)转换为字符串
	 * @param bs
	 * @return
	 */
	 public static String byteArray2String(byte[] bs){
		 StringBuffer sbLogRet = new StringBuffer();
		 for(int i=0; i<bs.length; i++)
		 {
			 String inTmp = String.format("%02x", bs[i]);
			 sbLogRet.append(inTmp);
		 }
		 return sbLogRet.toString();
	 }
	 
	 /**
	 * 16进制字符串到byte数组的转换
	 * @param hex	需要转换的字符串(只包含0~9,a~f字符)
	 * @return
	 */
	 public static byte[] AscToBcd(String hex)
	 {
		 //A null string returns an empty array
		 if (hex == null || hex.length() == 0) {
			 return new byte[0];
		 } else if (hex.length() < 3) {
			 return new byte[]{ (byte)(Integer.parseInt(hex, 16) & 0xff) };
		 }
		 //Adjust accordingly for odd-length strings
		 int count = hex.length();
		 int nibble = 0;
		 if (count % 2 != 0) {
			 count++;
			 nibble = 1;
		 }
		 byte[] buf = new byte[count / 2];
		 char c = 0;
		 int holder = 0;
		 int pos = 0;
		 for (int i = 0; i < buf.length; i++) {
			 for (int z = 0; z < 2 && pos<hex.length(); z++) {
				 c = hex.charAt(pos++);
				 if (c >= 'A' && c <= 'F') {
					 c -= 55;
				 } else if (c >= '0' && c <= '9') {
					 c -= 48;
				 } else if (c >= 'a' && c <= 'f') {
					 c -= 87;
				 }
				 if (nibble == 0) {
					 holder = c << 4;
				 } else {
					 holder |= c;
					 buf[i] = (byte)holder;
				 }
				 nibble = 1 - nibble;
			 }
		 }
		 return buf;
	}
	 /**
	  * 
	  * @param String
	  * @return 
	  * @description 16进制字符串到byte数组的转换(2个16进制字符转换为1个带符号10进制byte)
	  */
	 public static byte[] hexStringToByte(String s) {
			byte[] baKeyword = new byte[s.length() / 2];
			for (int i = 0; i < baKeyword.length; i++) {
				try {
					baKeyword[i] = (byte) (0xff & Integer.parseInt(
							s.substring(i * 2, i * 2 + 2), 16));
				} catch (Exception e) {
					LogUtil.error("十六进制转byte发生错误!!!"+s);
				}
			}
			return baKeyword;
		}
}

 

 

import java.nio.channels.FileChannel;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.Security;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Arrays;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.apache.coyote.http2.ByteUtil;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * AES加解密Util
 */
public class AESUtil {
	private static final Logger log = LoggerFactory.getLogger(AESUtil.class);
	
	private static final String DEFAULT_ENCODING = "UTF-8";
	private static final int KEY_SIZE = 128;
	public static final String KEY_ALGORITHM = "AES";
	public static final String CIPHER_ALGORITHM = "AES/ECB/PKCS7Padding";
	public static final String CIPHER_ALGORITHM_CBC = "AES/CBC/PKCS5Padding";
	
	public static final byte[] iv = { (byte) 0xf9, (byte) 0x5B, (byte) 0xC3, (byte) 0x34,
	      (byte) 0x94, (byte) 0x1e, (byte) 0xD8, (byte) 0xa7,
	      (byte) 0xA6, (byte) 0x61, (byte) 0xFF, (byte) 0x2B,
          (byte) 0x56, (byte) 0xcB, (byte) 0x47, (byte) 0x03};
	public static final AlgorithmParameterSpec spec =new IvParameterSpec(iv);
	  
	public static SecretKeySpec getSecretKeyWithSHA256(String key) throws Exception {
		return new SecretKeySpec(key.getBytes(), KEY_ALGORITHM);
	}

    /**
     * 加密
     * @param plainText 待加密字符串
     * @param key 秘钥
     * @return 加密结果字符串
     */
	public static String encrypt(String plainText, String key) {
		String encryptedText = null;
		if (StringUtils.isBlank(plainText)||"null".equals(plainText)) {
			return plainText;
		}
		try {
			Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_CBC);
			cipher.init(Cipher.ENCRYPT_MODE, getSecretKeyWithSHA256(key), spec);
			byte[] encrypted = cipher.doFinal(plainText.getBytes(DEFAULT_ENCODING));
			encryptedText = Base64.encodeBase64URLSafeString(encrypted);
		} catch (Exception e) {
			log.error("AES加密异常!!!",e);
		}
		return encryptedText;
	}

	/**
	 * 解密
	 * @param cryptedText 待解密字符串
	 * @param key 秘钥
	 * @return 解密结果字符串
	 */
	public static String decrypt(String cryptedText, String key) {
		String decryptedText = null;
		if (StringUtils.isBlank(cryptedText)||"null".equals(cryptedText)) {
			return cryptedText;
		}
		try {
			Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_CBC);
			cipher.init(Cipher.DECRYPT_MODE, getSecretKeyWithSHA256(key), spec);
			byte[] bytes = Base64.decodeBase64(cryptedText);
			byte[] decrypted = cipher.doFinal(bytes);
			decryptedText = new String(decrypted, DEFAULT_ENCODING);
		} catch (Exception e) {
			log.error("AES解密异常!!!",e);
		}
		return decryptedText;
	}
    
    /**
	 * 生成指定长度的对称密钥
	 * @param length 密钥的bit位数,默认为128位
	 * @return
	 * @throws Exception 
	 */
	public static byte[] generateKey(int length, String keyAlg) throws Exception {
		//实例化密钥生成器
    	Security.addProvider(new BouncyCastleProvider());
    	KeyGenerator kg = null;
		try {
			kg = KeyGenerator.getInstance(keyAlg, "BC");
		} catch (NoSuchAlgorithmException e) {
			log.error("不存在此种对称密钥算法:" + keyAlg);
			throw new Exception("不存在此种对称密钥算法:" + keyAlg, e);
		} catch (NoSuchProviderException e) {
			log.error("NoSuchProviderException:BouncyCastleProvider");
			throw new Exception("NoSuchProviderException:BouncyCastleProvider", e);
		}  
    	//初始化密钥生成器,AES要求密钥长度为128位、192位、256位  
        kg.init(length); 
        //生成密钥  
        SecretKey secretKey = kg.generateKey(); 
        //log.debug("生成的AES密钥:" + ByteUtil.byteArray2String(secretKey.getEncoded()));
        //获取二进制密钥编码形式
        return secretKey.getEncoded();  
	}
    
    /**
     * 转换密钥
     * @param key 十六进制编码格式密钥
     * @return
     * @throws Exception
     */
    public static Key toKey(byte[] key, String keyAlg) throws Exception {
        SecretKey secretKey = new SecretKeySpec(key, keyAlg);
        return secretKey;
    }
    
    /** 
	 * 对称密钥加密
	 * @param byteContent 	需要加密的内容
	 * @param key  	AES密钥
	 * @param keyAlg	对称密钥算法密钥算法 (java6支持56位密钥,bouncycastle支持64位)
	 * @param cipherAlg	加解密算法/工作模式/填充方式 (JAVA6 支持PKCS5PADDING填充方式 ,Bouncy castle支持PKCS7Padding填充方式)
	 * @return 
	 */
	public static byte[] encrypt(byte[] byteContent, byte[] key, String keyAlg, String cipherAlg) throws Exception {  
        try {
        	//还原密钥  
            Key k = toKey(key, keyAlg);  
            //实例化 ,使用 PKCS7PADDING 填充方式,按如下方式实现,就是调用bouncycastle组件实现 Cipher.getInstance(CIPHER_ALGORITHM,"BC") 
            Security.addProvider(new BouncyCastleProvider());
            Cipher cipher=Cipher.getInstance(cipherAlg, "BC"); 
            //Cipher cipher = Cipher.getInstance(keyAlg);
            //初始化,设置为加密模式  
            cipher.init(Cipher.ENCRYPT_MODE, k);  
            //执行操作  
            return cipher.doFinal(byteContent);	
        } catch (NoSuchAlgorithmException e) {  
        	log.error("不存在此种对称密钥算法:" + keyAlg);
        	throw new Exception("不存在此种对称密钥算法:" + keyAlg, e);
        } catch (NoSuchPaddingException e) {  
        	log.error("NoSuchPaddingException");
        	throw new Exception("NoSuchPaddingException", e);
        } catch (InvalidKeyException e) {  
        	//log.error("无效的Key:" + Base64Utils.encode(key));
        	throw new Exception("无效的Key:", e);
        } catch (IllegalBlockSizeException e) {  
        	log.error("被加密内容长度无效");
        	throw new Exception("被加密内容长度无效", e);
        } catch (BadPaddingException e) {
        	log.error("BadPaddingException");
        	throw new Exception("BadPaddingException", e);
        }
	}  
	
	/**
	 * 对称密钥解密 
	 * @param content  	待解密内容 
	 * @param key 		解密密钥 
	 * @param keyAlg	对称密钥算法密钥算法 (java6支持56位密钥,bouncycastle支持64位)
	 * @param cipherAlg	加解密算法/工作模式/填充方式 (JAVA6 支持PKCS5PADDING填充方式 ,Bouncy castle支持PKCS7Padding填充方式)
	 * @return 
	 */  
	public static byte[] decrypt(byte[] content, byte[] key, String keyAlg, String cipherAlg) throws Exception {  
		try {
        	//还原密钥  
            Key k = toKey(key, keyAlg);  
            //实例化 ,使用 PKCS7PADDING 填充方式,按如下方式实现,就是调用bouncycastle组件实现 Cipher.getInstance(CIPHER_ALGORITHM,"BC") 
            Security.addProvider(new BouncyCastleProvider());
            Cipher cipher=Cipher.getInstance(cipherAlg, "BC");  
            //Cipher cipher = Cipher.getInstance(keyAlg);
            //初始化,设置为加密模式  
            cipher.init(Cipher.DECRYPT_MODE, k);  
            //执行操作  
            return cipher.doFinal(content);	
        } catch (NoSuchAlgorithmException e) {  
        	log.error("不存在此种对称密钥算法:" + keyAlg);
        	throw new Exception("不存在此种对称密钥算法:" + keyAlg, e);
        } catch (NoSuchPaddingException e) {  
        	log.error("NoSuchPaddingException");
        	throw new Exception("NoSuchPaddingException", e);
        } catch (InvalidKeyException e) {  
        	//log.error("无效的Key:" + ByteUtil.byteArray2String(key));
        	throw new Exception("无效的Key:" , e);
        } catch (IllegalBlockSizeException e) {  
        	log.error("被加密内容长度无效");
        	throw new Exception("被加密内容长度无效", e);
        } catch (BadPaddingException e) {
        	log.error("BadPaddingException");
        	throw new Exception("BadPaddingException", e);
        }
	}  
	
	/**
	 * 固定IV偏移向量的AES加密算法
	 * 用于前后端全加密  慎用
	 * @author PENGKANGKANG620
	 * @param content
	 * @param key
	 * @return
	 */
	public static String encryptWithIV(String content, String key){
		try{
			Key keySpec = new SecretKeySpec(key.getBytes(), KEY_ALGORITHM);//两个参数,第一个为私钥字节数组, 第二个为加密方式 AES或者DES
            //String iv   = key;//初始化向量参数,AES 为16bytes. DES 为8bytes.
            IvParameterSpec ivSpec = new IvParameterSpec(key.getBytes());
            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_CBC);
            cipher.init(Cipher.ENCRYPT_MODE, keySpec,ivSpec);

            byte[] byteResult = cipher.doFinal(content.getBytes("UTF-8"));
            return new Base64().encodeToString(byteResult);
		}catch(Exception e){
			log.error("AES加密异常!!!");
		}
		return null;
	}
	
	/**
	 * 固定IV偏移向量的AES解密算法
	 * 用于前后端全加密
	 * @author PENGKANGKANG620
	 * @param content
	 * @param key
	 * @return
	 */
	public static String decryptWithIV(String content, String key){
		try{
			Key keySpec = new SecretKeySpec(key.getBytes(), KEY_ALGORITHM);    //两个参数,第一个为私钥字节数组, 第二个为加密方式 AES或者DES
           // String iv   = key;//初始化向量参数,AES 为16bytes. DES 为8bytes.
            IvParameterSpec ivSpec = new IvParameterSpec(key.getBytes());
            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_CBC);
            cipher.init(Cipher.DECRYPT_MODE, keySpec,ivSpec);
            byte[] tmp =  new Base64().decode(content.getBytes("UTF-8"));
            byte[] result = cipher.doFinal(tmp);  
            return new String(result,"UTF-8");
		}catch(Exception e){
			log.error("AES解密异常!!!");
		}
		return null;
		
	}
	/**
	 * 创建文件
	 * @param fileName
	 * @param filePath
	 * @param data
	 */
	public static void writeFile(String fileName,String filePath, byte[] data){
		BufferedOutputStream bufferOut = null;
		try{
			File f = new File(filePath);
			if (!f.exists()) {
				f.mkdirs();
			}
			bufferOut = new BufferedOutputStream(new FileOutputStream(filePath+fileName));
			bufferOut.write(data);
			bufferOut.flush();
		}catch(Exception e){
			log.error(e.getClass().getName() + "生成文件失败:"
					+ e.getMessage());
//			e.printStackTrace();
		} finally{
			if(null != bufferOut){
				try {
					bufferOut.close();
				} catch (IOException e) {
					log.error(e.getClass().getName() + "输出流关闭失败:"
							+ e.getMessage());
				}
			}
		}
	}
	
	/**
	 * 生成随机密钥
	 * 
	 * @return
	 * @throws Exception
	 */
	public static String getSecretKey() throws Exception {
		return getSecretKey(null);
	}

	/**
	 * 生成密钥
	 * @param seed 密钥种子
	 * @return
	 * @throws Exception
	 */
	public static String getSecretKey(String seed) throws Exception {
		KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM);
		SecureRandom secureRandom;
		if (seed != null && !"".equals(seed)) {
			secureRandom = new SecureRandom(seed.getBytes());
		} else {
			secureRandom = new SecureRandom();
		}
		keyGenerator.init(KEY_SIZE, secureRandom);
		SecretKey secretKey = keyGenerator.generateKey();
		return Base64Utils.encode(secretKey.getEncoded());
		
	}

	/**
	 * 加密
	 * @param data
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static byte[] encrypt(byte[] data, String key) throws Exception {
		Key k = toKey(Base64Utils.decode(key));
		byte[] raw = k.getEncoded();
		SecretKeySpec secretKeySpec = new SecretKeySpec(raw, KEY_ALGORITHM);
		Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
		cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
		return cipher.doFinal(data);
		
	}

	/**
	 * 解密
	 * @param base64data
	 * @param key
	 * @throws Exception
	 */
	public static byte[] decrypt(byte[] base64data, String key) throws Exception {
		Key k = toKey(Base64Utils.decode(key));
		byte[] raw = k.getEncoded();
		SecretKeySpec secretKeySpec = new SecretKeySpec(raw, KEY_ALGORITHM);
		Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
		cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
		return cipher.doFinal(base64data);
	}

	/**
	 * 转换密钥
	 * @param key
	 * @return
	 * @throws Exception
	 */
	private static Key toKey(byte[] key) throws Exception {
		SecretKey secretKey = new SecretKeySpec(key, KEY_ALGORITHM);
		return secretKey;
	}	
	 /**
	  * 
	  * @param sSrc
	  * @param sKey
	  * @param ivParameter
	  * @return
	  * @throws Exception
	  */
	public static String encrypt(String sSrc,String sKey, String ivParameter) throws Exception {
		Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_CBC);
		byte[] raw = sKey.getBytes();
		SecretKeySpec skeySpec = new SecretKeySpec(raw, KEY_ALGORITHM);
		IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes());// 使用CBC模式,需要一个向量iv,可增加加密算法的强度
		cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
		byte[] encrypted = cipher.doFinal(sSrc.getBytes(DEFAULT_ENCODING));
		return Base64Utils.encode(encrypted);// 此处使用BASE64做转码。
	}
	  public static void main(String[] args) throws Exception {
			byte[] AESkey = generateKey(128, KEY_ALGORITHM);
			AESkey = ByteUtil.AscToBcd("FA4246228215E27F03628A507296A2FC");
			byte[] needEncryptData = "hello".getBytes();
			byte[] dataAfterEnctypt = encrypt(needEncryptData, AESkey, KEY_ALGORITHM, CIPHER_ALGORITHM);
			System.out.println("dataAfterEnctypt:" + ByteUtil.byteArray2String(dataAfterEnctypt));
			System.out.println("dataAfterDectypt:" + new String(decrypt(dataAfterEnctypt, AESkey, KEY_ALGORITHM, CIPHER_ALGORITHM)));
			System.out.println(getSecretKey());
			System.out.println(decryptWithIV("do5vVB8IJVnK9+pK416AMg==", "NgzIKRmsV8ZtOw=="));
			String aes_key_Acc_Pri="NgzIKRmsV8ZtOw==";
			String accountId="123456";
			accountId = AESUtil.encryptWithIV(accountId, aes_key_Acc_Pri);
			System.out.println(accountId);
			accountId = AESUtil.decrypt("5XyVSoDM0qlrASG9QwnBeg", aes_key_Acc_Pri);
			System.out.println(accountId);

			System.out.println(decrypt(ByteUtil.AscToBcd("edde9e971337665ef05aedcbb86d3ee6"), AESkey, KEY_ALGORITHM, CIPHER_ALGORITHM));
			System.out.println(Arrays.toString(decrypt(ByteUtil.AscToBcd("edde9e971337665ef05aedcbb86d3ee6"), AESkey, KEY_ALGORITHM, CIPHER_ALGORITHM)));
			long startTime = System.currentTimeMillis();
			File file = new File("ss_j2ee/src/java/com/paic/cfs/test.jpg");
			FileInputStream fis= new FileInputStream(file);
			FileChannel fc= fis.getChannel();
			int fileSize = (int)fc.size();
			System.out.println("文件大小:" + fileSize);
			System.out.println("读取文件大小耗时:" + (System.currentTimeMillis() - startTime));
			
			byte[] bs_ogin = new byte[fileSize];
			fis.read(bs_ogin);
			
			dataAfterEnctypt = encrypt(bs_ogin, AESkey, KEY_ALGORITHM, CIPHER_ALGORITHM);
			System.out.println("dataAfterEnctypt:" + ByteUtil.byteArray2String(dataAfterEnctypt));
			writeFile("test.txt", "ss_j2ee/src/java/com/paic/cfs/", ByteUtil.byteArray2String(dataAfterEnctypt).getBytes());
			byte[] dataAfterDecrypt = decrypt(dataAfterEnctypt, AESkey, KEY_ALGORITHM, CIPHER_ALGORITHM);
			System.out.println("dataAfterDectypt:" + new String(dataAfterDecrypt));
			System.out.println((ByteUtil.byteArray2String(bs_ogin)).equals(ByteUtil.byteArray2String(dataAfterDecrypt)));
			writeFile("test_plain.jpg", "ss_j2ee/src/java/com/paic/cfs/", dataAfterDecrypt);*/
			
			File file1 = new File("ss_j2ee/src/java/com/paic/cfs/renlian.txt");
			BufferedReader br = new BufferedReader(new FileReader(file1));
			String fileContent = br.readLine();
			byte[] dataAfterDecrypt = decrypt(ByteUtil.AscToBcd(fileContent), AESkey, KEY_ALGORITHM, CIPHER_ALGORITHM);
			writeFile("renlian.jpg", "ss_j2ee/src/java/com/paic/cfs/", dataAfterDecrypt);
		}
	    
	
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值