AES

package com.topsec.ws.util;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;

/**
 * AES加密使用的工具类
 * 
加密算法为密钥长度为128位的AES算法,算法运行模式选择CBC模式,填充模式选择PKCS5Padding,
加密时使用的初始化向量固定为0000000000000000。生成密文后,发送方需要将密文按16进制编码再进行接口调用实现网络传输;
收到密文后,接收方需要进行逆过程用以解密。

当且仅当安全管理软件采用WSSmCommLower中的fillConfig接口向安全设备下发通信参数配置(SDMI_Config_1.00)时,
oprCode不加密,configXml使用密钥12345678901234567890123456789012按照上述加密方式进行加密。

WSSmUpper中每一个report接口的deviceID参数均不加密。

其余通信内容(包括WSSmCommLower和WSSmCommUpper中的其余任意接口的任意参数,
以及WSSmCommLower.fillConfig接口中的数据上报配置和界面集成配置)中的oprCode和xml,
加密密钥为设备ID的小写md5值(设备ID为SDMI_Config_1.00里面下发的DeviceId)。

经加密后的通信内容中,合法的16进制字符包括0123456789abcdef,以及仅在deviceID字段中可能出现的连接符-
出现其余任意字符均会被判定不合法从而导致验证失败。

使用过程中,安全管理软件可能会在下发的通信参数配置(SDMI_Config_1.00)里重新为安全设备分配DeviceId,
此时安全设备应注意在通信过程中使用新的密钥对相关信息进行加解密。
 * 
 * @author hx
 * @date 2015年10月23日
 */
public class AESTool {

   private static final String ALGORITHM = "AES";//加密算法
   private static final String MODE = "AES/CBC/PKCS5Padding";// 运行模式:包含 加密算法/运算模式/填充模式,此处采用CBC
// private static final String MODE = "AES/ECB/NoPadding";// 运行模式:包含 加密算法/运算模式/填充模式,此处采用CBC
   private static String initialVector = "0000000000000000"; //初始化向量,必须为长度为16的字符串
   
   public static final char HEX_DIGITS[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };//合法的16进制值
   
   /**
    * 对传入的byte数组加密,返回一个byte数组
    * @param data 待加密内容
    * @param key 密钥长度必须为128字节,即32位16进制字符串
    * @return
    * @throws Exception
    */
   public static byte[] encrypt(byte[] data, String key, String iv) throws Exception {
      byte[] keyBytes = Hex2ByteArray(key);
      Key keySpec = new SecretKeySpec(keyBytes, ALGORITHM);
      
      Cipher cipher = Cipher.getInstance(MODE);
      IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes("UTF-8"));
      
      cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
      return cipher.doFinal(data);
   }
   
   /**
    * 对传入的String加密,返回一个16进制字符串
    * @param key
    * @param iv
    * @return
    * @throws Exception
    */
   public static String encrypt(String toEnc, String key, String iv) throws Exception{
      return toHexString(encrypt(toEnc.getBytes("UTF-8"), key, iv));
   }
   
   /**
    *     对传入的byte数组解密,返回一个原始字符串
    * @param data 待解密内容
    * @param key 密钥长度必须为128字节,即32位16进制字符串
    * @return
    * @throws Exception
    */
   public static String decrypt(byte[] data, String key, String iv) throws Exception {
      byte[] keyBytes = Hex2ByteArray(key);
      Key keySpec = new SecretKeySpec(keyBytes, ALGORITHM);
      
      Cipher cipher = Cipher.getInstance(MODE);
      IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes("UTF-8"));
      
      cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
      return new String(cipher.doFinal(data), "UTF-8").trim();
   }
   
   /**
    * 传入经16进制编码后的加密内容,尝试对其解密,返回明文String
    * 
    * @param encryptedHEX
    * @param key
    * @param iv
    * @throws Exception
    */
   public static String decrypt(String encryptedHEX, String key, String iv) throws Exception{
      return decrypt(Hex2ByteArray(encryptedHEX), key, iv);
   }
   
   /**
    * 将16进制字符串转换为byte数组
    * 
    * @param stringHEX 16进制字符串,只能出现0123456789abcdef
    * @return
    */
   public static byte[] Hex2ByteArray(String stringHEX) {
      byte[] bufferByte = new byte[stringHEX.length() / 2];
      try {
         List bufferls = new ArrayList();
         Integer j = 0;
         for (int i = 2; i < stringHEX.length() + 2; i = i + 2) {
            bufferls.add(Integer.decode("0x" + stringHEX.substring(j, i)));
            j = i;
         }
         for (int i = 0; i < bufferls.size(); i++) {
            bufferByte[i] = bufferls.get(i).byteValue();
         }
      } catch (Exception ex) {
         ex.printStackTrace();
      }
      return bufferByte;
   }
   
   /**
    * Byte数组转16进制编码字符串
    * @param b
    * @return
    */
   public static String toHexString(byte[] b) {
      StringBuffer buffer = new StringBuffer();
      for (byte ts : b) {
         String hex = Integer.toHexString(ts & 0xff);
         if (hex.length() == 1) {
            hex = '0' + hex;
         }
         buffer.append(hex);
      }
      return buffer.toString();
   }
   
   /**
    * 输入一个String , 返回其MD5值
    * 
    * @param s
    * @return
    */
   public static String getMD5(String s) {
      try {
         MessageDigest digest = MessageDigest.getInstance("MD5");
         digest.update(s.getBytes());
         byte messageDigest[] = digest.digest();
         return toHexString(messageDigest);
      } catch (NoSuchAlgorithmException e) {
         e.printStackTrace();
      }
      return "";
   }

   
   public static void main(String[] args)  throws Exception{
      String str = "429124dfb8173147ec12883797271fff6db5" +
            "4ee40b56b5512e6e6431f7c6fc54051c3dfdc3a77cc3faadf6" +
            "73fba7cdb09d7058afc6c43dd3fbcea7dffb5464d32ab8ced5fba" +
            "2814acf6148249661a4b07b94de3094fc6453522b5268b21f045b09d8" +
            "acfbdfa49d4cc56c07db233ed7bb61fa4c21a0119440ef5cad8f4d442dc7e" +
            "a9ec939083eac0df19860f7e1440e37e1b2c75e6d2579a1059dac86b18046fd00b" +
            "e050dcc64daeace616e90a5974e2fba4036633cc02489ca7557f434493318f51f3982107d" +
            "bfe5b1a56c432101a4abf5f729e1f385a3801201e3315f71ea30";
      String keyString = "ba7080056f71479d4caa08c4f6b2a6d2";
      /*
      2018.05.12 jiayonghui
      String keyString2 = "3d24e19bbe35d813a25722ce2dda992e";*/
      
      String decrypted = decrypt(str, keyString, initialVector);
      System.out.println("解密后:"+decrypted);
   }
   
   
   
   
   
   /*public static void main(String[] args) {
      String keyString  = "12345678901234567890123456789012";
      System.out.println("密钥:"+keyString);
      String toEnc = ""
         + ""
         + ""
         + "192.168.12.78"
         + "8080"
         + "1000-19ec-4089-9f08-b5c537ee8c7225d022a2-9f0f-421e-8ac8-498f57e03cff"
         + "" + "";
      System.out.println("加密前:"+toEnc);
      try {
         String encryptedHex = encrypt(toEnc, keyString, initialVector);
         System.out.println("加密后:"+encryptedHex);
         
         String decrypted = decrypt(encryptedHex, keyString, initialVector);
         System.out.println("解密后:"+decrypted);
      } catch (Exception e) {
         e.printStackTrace();
      }
   }*/

}

你可能感兴趣的:(java)