AES加密,128-192-256,方案一

来源:互联网 发布:org.apache server 编辑:程序博客网 时间:2024/06/05 04:56

AES加密。

直接粘贴代码,异常什么的自己要处理,做个总结记录



package com.xiao.aes.util;

import java.io.UnsupportedEncodingException;
import java.security.SecureRandom;

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

/**
 * 美国软件出口限制,JDK默认使用的AES算法最高只能支持128位。如需要更高的支持需要从oracle官网下载更换JAVA_HOME/jre/lib/
 * security目录下的: local_policy.jar和US_export_policy.jar。<br/>
 * 对应的AES加解密的KEY的长度:128-16、192-24、256-32.<br/>
 * jdk1.7下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html <br/>
 *
 * @author xiao
 *
 */
public class AESUtil1 {

 /**
  * 随机生成密钥的数据源
  */
 private static final String KEY_SOURCE = "qwertyuiopasdfghjklzxcvbnm1234567890";

 /**
  * 生成指定类型的AESkey的长度
  *
  * @param type
  *            AES类型
  * @return key
  */
 public static String createAESKey(AESType type) {
  int length = type.value / 8;
  StringBuffer keySB = new StringBuffer();
  SecureRandom random = new SecureRandom();
  int sourceL = KEY_SOURCE.length();
  for (int i = 0; i < length; i++) {
   int index = random.nextInt(sourceL);
   keySB.append(KEY_SOURCE.charAt(index));
  }
  return keySB.toString();
 }

 /**
  * AES加密,返回秘文
  *
  * @param plaintext
  *            明文
  * @param key
  *            加密key
  * @param type
  *            加密类型
  * @return 秘文
  */
 public static String encryptAES(String plaintext, String key, AESType type) {
  byte[] result = encrypt(plaintext, key, type.value);
  return parseByte2HexStr(result);
 }

 /**
  * AES解密
  *
  * @param ciphertext
  *            秘文
  * @param key
  *            加密key
  * @param type
  *            加密类型
  * @return 明文
  */
 public static String decryptAES(String ciphertext, String key, AESType type) {
  byte[] result = parseHexStr2Byte(ciphertext);
  byte[] plainByte = decrypt(result, key, type.value);
  try {
   return new String(plainByte, "utf-8");
  } catch (UnsupportedEncodingException e) {
   e.printStackTrace();
  }
  return "";
 }

 /**
  * 加密
  *
  * @param content
  *            需要加密的内容
  * @param password
  *            加密密码
  * @return
  */
 public static byte[] encrypt(String content, String password, int aesLength) {
  try {
   KeyGenerator kgen = KeyGenerator.getInstance("AES");
   kgen.init(aesLength, new SecureRandom(password.getBytes()));
   SecretKey secretKey = kgen.generateKey();
   byte[] enCodeFormat = secretKey.getEncoded();
   SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
   // 创建密码器
   Cipher cipher = Cipher.getInstance("AES");
   byte[] byteContent = content.getBytes("utf-8");
   // 初始化
   cipher.init(Cipher.ENCRYPT_MODE, key);
   byte[] result = cipher.doFinal(byteContent);
   return result; // 加密
  } catch (Exception e) {
   e.printStackTrace();
  }
  return null;
 }

 /**
  * 解密
  *
  * @param content
  *            待解密内容
  * @param password
  *            解密密钥
  * @param aesLenth
  *            AES加密类型,128、192、256
  * @return
  */
 public static byte[] decrypt(byte[] content, String password, int aesLength) {
  try {
   KeyGenerator kgen = KeyGenerator.getInstance("AES");
   kgen.init(aesLength, new SecureRandom(password.getBytes()));
   SecretKey secretKey = kgen.generateKey();
   byte[] enCodeFormat = secretKey.getEncoded();
   SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
   Cipher cipher = Cipher.getInstance("AES");// 创建密码器
   cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
   byte[] result = cipher.doFinal(content);
   return result; // 加密
  } catch (Exception e) {
   e.printStackTrace();
  }
  return null;
 }

 /**
  * 将二进制转换成16进制
  *
  * @param buf
  * @return
  */
 private static String parseByte2HexStr(byte buf[]) {
  StringBuffer sb = new StringBuffer();
  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
  */
 private 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) {
  String key = createAESKey(AESType.AES_192);
  System.out.println("密钥:" + key);
  String plaintext = "AES Test!";
  String ciphertext = encryptAES(plaintext, key, AESType.AES_192);
  System.out.println("秘文:" + ciphertext);
  plaintext = decryptAES(ciphertext, key, AESType.AES_192);
  System.out.println("明文:" + plaintext);
 }
}


测试结果:

密钥:pm95sgzpms1dcwfsp50m8avu
秘文:7E615B76E81328DBC2D4BD8DBD94C3F3
明文:AES Test!


贴上AESType枚举类,主要是起限制作用,让AES的参数值仅支持128,192,256

package com.xiao.aes.util;

/**
 * AES加密类型枚举
 *
 * @author xiao
 *
 */
public enum AESType {
 AES_128(128), AES_192(192), AES_256(256);

 public int value;

 private AESType(int value) {
  this.value = value;
 }

 public int getValue() {
  return value;
 }

 public void setValue(int value) {
  this.value = value;
 }
}

 


另外还有一种更简洁的尚在调试:




1 0