当前位置 : 主页 > 编程语言 > java >

3DES加密解密的工具类

来源:互联网 收集:自由互联 发布时间:2021-06-28
gistfile1.txt 今天看到一段3DES加密算法的代码,用的参数是DESede/CBC/PKCS5Padding,感觉比较陌生,于是学习了一下。遇到的java代码如下:Cipher cipher=Cipher.getInstance("DESede/CBC/PKCS5Padding");以前写
gistfile1.txt
今天看到一段3DES加密算法的代码,用的参数是DESede/CBC/PKCS5Padding,感觉比较陌生,于是学习了一下。
遇到的java代码如下:
Cipher cipher=Cipher.getInstance("DESede/CBC/PKCS5Padding");
以前写的代码,给的参数都是DES或DESede。实际上DESede是简写,它与DESede/ECB/PKCS5Padding等价。这个参数分为三段。
- 第一段是加密算法的名称,如DESede实际上是3-DES。这一段还可以放其它的对称加密算法,如Blowfish等。
- 第二段是分组加密的模式,除了CBC和ECB之外,还可以是NONE/CFB/QFB等。最常用的就是CBC和ECB了。DES采用分组加密的方式,将明文按8字节(64位)分组分别加密。如果每个组独立处理,则是ECB。CBC的处理方式是先用初始向量IV对第一组加密,再用第一组的密文作为密钥对第二组加密,然后依次完成整个加密操作。如果明文中有两个分组的内容相同,ECB会得到完全一样的密文,但CBC则不会。
- 第三段是指最后一个分组的填充方式。大部分情况下,明文并非刚好64位的倍数。对于最后一个分组,如果长度小于64位,则需要用数据填充至64位。PKCS5Padding是常用的填充方式,如果没有指定,默认的方式就是它。
补充一点,虽然DES的有效密钥长度是56位,但要求密钥长度是64位(8字节)。3DES则要求24字节(修改代码,32位密钥也可以)。




在CBC(不光是DES算法)模式下,iv通过随机数(或伪随机)机制产生是一种比较常见的方法。iv的作用主要是用于产生密文的第一个block,以使最终生成的密文产生差异(明文相同的情况下),使密码攻击变得更为困难,除此之外iv并无其它用途。因此iv通过随机方式产生是一种十分简便、有效的途径。
ThreeDEScbcUtil.java
package com.dmt.util;

import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;

/**
 * ThreeDEScbcUtil {3DES加密解密的工具类 }
 * 32位密钥  加密方式:DESede/CBC/PKCS5Padding
 * @author ly
 * @date 2017-11-16
 */
public class ThreeDEScbcUtil {

	//DES算法要求有一个可信任的随机数源,同一次加解密随机数要保持一致
	private static IvParameterSpec iv = null;
	
	public static IvParameterSpec ivDes3CBC(byte[] key){
		try {
			// DES算法要求有一个可信任的随机数源
			//此类提供加密的强随机数生成器 (RNG)。许多实现都是伪随机数生成器 (PRNG) 形式
			SecureRandom random = new SecureRandom();
			byte seed[] = random.generateSeed(8);//调用 generateSeed 方法来生成给定的种子字节数
		    iv = new IvParameterSpec(seed);  
	        System.out.println("十六进制的iv的随机数的ASCII:"+byteToHexASICC(seed));
		    return iv;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	// 加密数据
	public static byte[] encryptDes3CBC(byte[] message, byte[] key, IvParameterSpec iv) {
		try {
			// SecretKey secretKey = new SecretKeySpec(key, "DESede"); //密钥默认24位
			DESedeKeySpec dks = new DESedeKeySpec(key);// 密钥32位
			// 创建一个密匙工厂,然后用它把DESKeySpec转换成
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
			SecretKey securekey = keyFactory.generateSecret(dks);

			// encrypt
			Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
			cipher.init(Cipher.ENCRYPT_MODE, securekey, iv);
			// 现在,获取数据并加密
			// 正式执行加密操作
			byte[] encryptedData = cipher.doFinal(message);
			return encryptedData;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	// 解密密数据
	/**
	 * 功能:解密密数据  将byte[]的字节数组转ASICC码
	 * @param byte[] message 加密数据的字节数组
	 * @param byte[] key 密钥的字节数组
	 * @param IvParameterSpec iv 字节数组
     * @return ASICC码(也是16进制)
	 */
	public static byte[] decryptDes3CBC(byte[] message, byte[] key, IvParameterSpec iv) {
		try {
			// SecretKey secretKey = new SecretKeySpec(key, "DESede"); //密钥默认24位
			DESedeKeySpec dks = new DESedeKeySpec(key);// 密钥32位
			// 创建一个密匙工厂,然后用它把DESKeySpec转换成
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
			SecretKey securekey = keyFactory.generateSecret(dks);

			// decrypt
			// Cipher对象实际完成加密操作
			Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
			// 用密匙初始化Cipher对象
			cipher.init(Cipher.DECRYPT_MODE, securekey, iv);
			// 现在,获取数据并加密
			// 正式执行加密操作
			byte[] decryptPlainText = cipher.doFinal(message);
			return decryptPlainText;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 功能:将byte[]的字节数组转ASICC码
	 * @param bytes 字节数组
     * @return ASICC码(也是16进制)
	 */
	public static String byteToHexASICC(byte[] bytes) {
		StringBuffer sb = new StringBuffer(bytes.length);
		String sTemp;
		for (int i = 0; i < bytes.length; i++) {
			sTemp = Integer.toHexString(0xFF & bytes[i]);
			if (sTemp.length() < 2)
				sb.append(0);
			sb.append(sTemp.toUpperCase());
		}
		return sb.toString();
	}

	/**
	 * 功能:将十六进制字符串转换为字节数组
	 * 
	 * @param hex
	 *            十六进制字符串
	 * @return 字节数组
	 */
	public static byte[] hextobyte(String hex) {
		int len = hex.length();
		byte[] buf = new byte[(len + 1) / 2];
		int i = 0;
		int j = 0;
		if ((len % 2) == 1) {
			buf[j++] = (byte) hexchartoint(hex.charAt(i++));
		}
		while (i < len) {
			buf[j++] = (byte) ((hexchartoint(hex.charAt(i++)) << 4) | hexchartoint(hex
					.charAt(i++)));
		}
		return buf;
	}

	/**
	 * 功能:将十六进制的char转换为十进制的int值
	 * 
	 * @param ch
	 *            十六进制的char
	 * @return 十进制 int值
	 */
	public static int hexchartoint(char ch) {
		if (ch >= '0' && ch <= '9') {
			return ch - '0';
		}
		if (ch >= 'A' && ch <= 'F') {
			return ch - 'A' + 10;
		}
		if (ch >= 'a' && ch <= 'f') {
			return ch - 'a' + 10;
		}
		throw new IllegalArgumentException("invalid hex digit '" + ch + "'");
	}

	public static void main(String[] args) throws Exception {
		 // 添加新安全算法,如果用JCE就要把它添加进去
		 //Security.addProvider(new com.sun.crypto.provider.SunJCE());

		byte[] key = "1A2B3C4D5E6F78901234A5B6C7D8E9F0".getBytes();
		byte[] username = "bj_simsys".getBytes();

		  ivDes3CBC(key);//一次加解密所用的随机数必须是同一个
		 byte[] encryptPlainText = encryptDes3CBC(username,key,iv);
		 System.out.println("加密_3des_cbc: " + byteToHexASICC(encryptPlainText));

//		String ciperIV = PropertiesUtil.getValue("ciperIV");
//		IvParameterSpec iv = new IvParameterSpec(hextobyte(ciperIV));
//		byte[] decryptPlainText = decryptDes3CBC(hextobyte("D574F066CF044E7A7B4430CABE6B7C7F"), key, iv);
		 byte[] decryptPlainText = decryptDes3CBC(encryptPlainText, key, iv);
		System.out.println("解密_3des_cbc: " + new String(decryptPlainText));

	}
	
	
	//完整方法
	  /*  public static void main(String[] args) throws Exception {
//			// 添加新安全算法,如果用JCE就要把它添加进去
//			//Security.addProvider(new com.sun.crypto.provider.SunJCE());
			
			
	    	byte[] key = "1A2B3C4D5E6F78901234A5B6C7D8E9F0".getBytes();       
	        byte[] username = "bj_simsys".getBytes();  
	        IvParameterSpec iv = null; 
	          
	       // SecretKey secretKey = new SecretKeySpec(key, "DESede"); //密钥默认24位 
	        DESedeKeySpec dks = new DESedeKeySpec(key);//密钥32位 
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
			SecretKey securekey = keyFactory.generateSecret(dks);
			
			// DES算法要求有一个可信任的随机数源,同一次加解密随机数要保持一致
			SecureRandom random = new SecureRandom();
			byte seed[] = random.generateSeed(8);//调用 generateSeed 方法来生成给定的种子字节数
		    IvParameterSpec iv = new IvParameterSpec(seed); 
		    
			//encrypt  
	        Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding"); 
	        cipher.init(Cipher.ENCRYPT_MODE, securekey, iv);  
	        byte[] encryptedData = cipher.doFinal(username);  
	        System.out.println("encrypt_3des_cbc: " + byteToHexString(encryptedData));
	          
			//decrypt  
	        cipher.init(Cipher.DECRYPT_MODE, securekey, iv);  
	        byte[] decryptPlainText = cipher.doFinal(encryptedData); 
	        System.out.println("encrypt_3des_cbc22: " + new String(decryptPlainText));  
		}*/
	    

}
ThreeDESecbUtil.java
package com.dmt.util;

import java.io.UnsupportedEncodingException;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;

/**
 * ThreeDESecbUtil {3DES加密解密的工具类 }
 * 32位密钥  加密方式:DESede即DESede/ECB/PKCS5Padding
 * @author ly
 * @date 2017-11-15
 */
 public class ThreeDESecbUtil {
  
	 /** 定义加密算法,有DES、DESede(即3DES)、Blowfish*/
     private static final String Algorithm = "DESede";    
     /** 密钥 */
	 private static SecretKey securekey;
    
    /**
      * 加密方法
      * @param src 源数据的字节数组
      * @return 
      */
	public static byte[] encryptMode(String enKey, byte[] src) {
		try {
			DESedeKeySpec dks = new DESedeKeySpec(enKey.getBytes());
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(Algorithm);
			securekey = keyFactory.generateSecret(dks);

			Cipher c1 = Cipher.getInstance(Algorithm); // 实例化负责加密/解密的Cipher工具类
			c1.init(Cipher.ENCRYPT_MODE, securekey); // 初始化为加密模式
			return c1.doFinal(src);
		} catch (java.security.NoSuchAlgorithmException e1) {
			e1.printStackTrace();
		} catch (javax.crypto.NoSuchPaddingException e2) {
			e2.printStackTrace();
		} catch (java.lang.Exception e3) {
			e3.printStackTrace();
		}
		return null;
	}
   
    
	/**
	 * 解密函数
	 * @param src 密文的字节数组
	 * @return
	 */
	public static byte[] decryptMode(String enKey, byte[] src) {
		try {
			DESedeKeySpec dks = new DESedeKeySpec(enKey.getBytes());
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(Algorithm);
			securekey = keyFactory.generateSecret(dks);

			Cipher c = Cipher.getInstance(Algorithm);
			c.init(Cipher.DECRYPT_MODE, securekey); // 初始化为解密模式
			return c.doFinal(src);
		} catch (java.security.NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (javax.crypto.NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (java.lang.Exception e3) {
			e3.printStackTrace();
		}
		return null;
	}
	
	/**
     *  功能:将十六进制字符串转换为字节数组
     * @param hex 十六进制字符串
     * @return byte 字节数组
     */
    public static byte[] hextobyteString(String hex) {
        int len = hex.length();
        byte[] buf = new byte[(len + 1) / 2];
        int i = 0;
        int j = 0;
        if ((len % 2) == 1) {
            buf[j++] = (byte) hexchartoint(hex.charAt(i++));
        }
        while (i < len) {
            buf[j++] = (byte) ((hexchartoint(hex.charAt(i++)) << 4) | hexchartoint(hex.charAt(i++)));
        }
        return buf;
    }
    
    /**
     * (将十六进制的char转换为十进制的int值)
     */
    public static int hexchartoint(char ch) {
        if (ch >= '0' && ch <= '9') {
            return ch - '0';
        }
        if (ch >= 'A' && ch <= 'F') {
            return ch - 'A' + 10;
        }
        if (ch >= 'a' && ch <= 'f') {
            return ch - 'a' + 10;
        }
        throw new IllegalArgumentException("invalid hex digit '" + ch + "'");
    }
     
	/**
	 * 根据字符串生成密钥字节数组
	 * 
	 * @param keyStr
	 *            密钥字符串
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static byte[] build3DesKey(String keyStr)throws UnsupportedEncodingException {
		byte[] key = new byte[24]; // 声明一个位的字节数组,默认里面都是0
		byte[] temp = keyStr.getBytes("UTF-8"); // 将字符串转成字节数组

		/*
		 * 执行数组拷贝 System.arraycopy(源数组,从源数组哪里开始拷贝,目标数组,拷贝多少位)
		 */
		if (key.length > temp.length) {
			// 如果temp不够位,则拷贝temp数组整个长度的内容到key数组中
			System.arraycopy(temp, 0, key, 0, temp.length);
		} else {
			// 如果temp大于位,则拷贝temp数组个长度的内容到key数组中
			System.arraycopy(temp, 0, key, 0, key.length);
		}
		System.out.println("【十六进制24字节-密钥】:1A2B3C4D5E6F78901234");
		// System.out.println("【ASCII-密钥】:"+byteToHexString(key));

		return key;
	}
    
    //字节(二进制)转ASICC码
    public static String byteToHexString(byte[] bytes) {
        StringBuffer sb = new StringBuffer(bytes.length);
        String sTemp;
        for (int i = 0; i < bytes.length; i++) {
            sTemp = Integer.toHexString(0xFF & bytes[i]);
            if (sTemp.length() < 2)
                sb.append(0);
            sb.append(sTemp.toUpperCase());
        }
        return sb.toString();
    }
    
    public static void main(String[] args) {
         String msg = "bj_simsys";//3DES加密解密案例
         String key = "1A2B3C4D5E6F78901234A5B6C7D8E9F0";//3DES加密解密案例
         System.out.println("【加密前】:" + msg);
         
         //加密
         byte[] secretArr = ThreeDESecbUtil.encryptMode(key, msg.getBytes());    
        // System.out.println("【加密后】:" + new String(secretArr));
         System.out.println("【加密后】:"+byteToHexString(secretArr));
         
         //解密
         byte[] myMsgArr = ThreeDESecbUtil.decryptMode(key, secretArr);  
        System.out.println("【解密后】:" + new String(myMsgArr));
     }
 }
DES.java
package com.dmt.des;

import java.security.SecureRandom;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.SecretKeyFactory;
import javax.crypto.SecretKey;
import javax.crypto.Cipher;


/**
 * DES加密介绍 DES是一种对称加密算法,所谓对称加密算法即:加密和解密使用相同密钥的算法。DES加密算法出自IBM的研究,
 * 后来被美国政府正式采用,之后开始广泛流传,但是近些年使用越来越少,因为DES使用56位密钥,以现代计算能力,
 * 24小时内即可被破解。虽然如此,在某些简单应用中,我们还是可以使用DES加密算法,本文简单讲解DES的JAVA实现 。
 * 注意:DES加密和解密过程中,密钥长度都必须是8的倍数
 */
public class DES {
	
	public static void main(String args[]) {
		// 待加密内容
		String username = "bj_simsys";// 测试内容
		// 密码,长度要是8的倍数
		String key = "1A2B3C4D5E6F78901234A5B6C7D8E9F0";

		byte[] result = DES.encrypt(username.getBytes(), key);
		//System.out.println("解密后:" + new String(result));//字节看不懂
		System.out.println("加密后:" + byteToHexString(result));
		
		//解密
		byte[] decryResult = DES.decrypt(result, key);
		System.out.println("解密后:" + new String(decryResult));
	}

	/**
	 * 加密
	 * 
	 * @param datasource
	 *            byte[]
	 * @param password
	 *            String
	 * @return byte[]
	 */
	public static byte[] encrypt(byte[] datasource, String password) {
		try {
			SecureRandom random = new SecureRandom();
			DESKeySpec desKey = new DESKeySpec(password.getBytes());
			// 创建一个密匙工厂,然后用它把DESKeySpec转换成
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
			SecretKey securekey = keyFactory.generateSecret(desKey);
			// Cipher对象实际完成加密操作
			Cipher cipher = Cipher.getInstance("DES");
			// 用密匙初始化Cipher对象
			cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
			// 现在,获取数据并加密
			// 正式执行加密操作
			return cipher.doFinal(datasource);
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 解密
	 * 
	 * @param src
	 *            byte[]
	 * @param password
	 *            String
	 * @return byte[]
	 * @throws Exception
	 */
	public static byte[] decrypt(byte[] src, String password) {
		try {
			// DES算法要求有一个可信任的随机数源
			SecureRandom random = new SecureRandom();
			// 创建一个DESKeySpec对象
			DESKeySpec desKey = new DESKeySpec(password.getBytes());
			// 创建一个密匙工厂
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
			// 将DESKeySpec对象转换成SecretKey对象
			SecretKey securekey = keyFactory.generateSecret(desKey);
			// Cipher对象实际完成解密操作
			Cipher cipher = Cipher.getInstance("DES");
			// 用密匙初始化Cipher对象
			cipher.init(Cipher.DECRYPT_MODE, securekey, random);
			// 真正开始解密操作
			return cipher.doFinal(src);
		} catch (Exception e) {
			e.printStackTrace();
			return null; 
		}
	}
	
	
	/**
	 * 字节转ASICC码
	 */
    public static String byteToHexString(byte[] bytes) {
        StringBuffer sb = new StringBuffer(bytes.length);
        String sTemp;
        for (int i = 0; i < bytes.length; i++) {
            sTemp = Integer.toHexString(0xFF & bytes[i]);
            if (sTemp.length() < 2)
                sb.append(0);
            sb.append(sTemp.toUpperCase());
        }
        return sb.toString();
    }
}
Des3CBC.java
package com.dmt.des;

import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import org.apache.commons.net.nntp.NewGroupsOrNewsQuery;

public class Des3CBC {
	private static IvParameterSpec iv = null;
	
	public static IvParameterSpec ivDes3CBC(byte[] key){
		try {
			// DES算法要求有一个可信任的随机数源
			//此类提供加密的强随机数生成器 (RNG)。许多实现都是伪随机数生成器 (PRNG) 形式
			SecureRandom random = new SecureRandom();
			byte seed[] = random.generateSeed(8);//调用 generateSeed 方法来生成给定的种子字节数
		    iv = new IvParameterSpec(seed);  
		    System.out.println("十六进制的iv的随机数的ASCII:"+byteToHexASICC(seed));
		    return iv;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	// 加密数据
    public static byte[] encryptDes3CBC(byte[] message, byte[] key){
		try {
			//SecretKey secretKey = new SecretKeySpec(key, "DESede"); //密钥默认24位 
	        DESedeKeySpec dks = new DESedeKeySpec(key);//密钥32位 
	   	 	// 创建一个密匙工厂,然后用它把DESKeySpec转换成
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
			SecretKey securekey = keyFactory.generateSecret(dks);
			
			//encrypt  
	        Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");  
	        cipher.init(Cipher.ENCRYPT_MODE, securekey, iv);  
	        // 现在,获取数据并加密
			// 正式执行加密操作
	        byte[] encryptedData = cipher.doFinal(message); 
	        return encryptedData;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null; 
    }
    
    // 解密密数据
    public static byte[] decryptDes3CBC(byte[] message, byte[] key){
 		try {
 			//SecretKey secretKey = new SecretKeySpec(key, "DESede"); //密钥默认24位 
	        DESedeKeySpec dks = new DESedeKeySpec(key);//密钥32位 
	   	 	// 创建一个密匙工厂,然后用它把DESKeySpec转换成
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
			SecretKey securekey = keyFactory.generateSecret(dks);
			
 			//decrypt 
 			// Cipher对象实际完成加密操作
 		    Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding"); 
 		    // 用密匙初始化Cipher对象
 	        cipher.init(Cipher.DECRYPT_MODE, securekey, iv); 
 	        // 现在,获取数据并加密
			// 正式执行加密操作
 	        byte[] decryptPlainText = cipher.doFinal(message);   
 	        return decryptPlainText;
 		} catch (Exception e) {
 			e.printStackTrace();
 		}
 		return null; 
    }
    
    public static String byteToHexASICC(byte[] bytes) {
        StringBuffer sb = new StringBuffer(bytes.length);
        String sTemp;
        for (int i = 0; i < bytes.length; i++) {
            sTemp = Integer.toHexString(0xFF & bytes[i]);
            if (sTemp.length() < 2)
                sb.append(0);
            sb.append(sTemp.toUpperCase());
        }
        return sb.toString();
    }
    public static void main(String[] args) throws Exception {
//		// 添加新安全算法,如果用JCE就要把它添加进去
//		//Security.addProvider(new com.sun.crypto.provider.SunJCE());
		
    	byte[] key = "1A2B3C4D5E6F78901234A5B6C7D8E9F0".getBytes();       
        byte[] username = "bj_simsys".getBytes();  
          
        ivDes3CBC(key);//一次加解密所用的随机数必须是同一个
      // IvParameterSpec iv = new IvParameterSpec("12345678".getBytes());  
        byte[] encryptPlainText = encryptDes3CBC(username,key);
        System.out.println("加密_3des_cbc: " + byteToHexASICC(encryptPlainText));
          
        byte[] decryptPlainText = decryptDes3CBC(encryptPlainText,key);
        System.out.println("解密_3des_cbc: " + new String(decryptPlainText));  
        
    }
    
    
    
    //完整方法
  /*  public static void main(String[] args) throws Exception {
//		// 添加新安全算法,如果用JCE就要把它添加进去
//		//Security.addProvider(new com.sun.crypto.provider.SunJCE());
		
		
    	byte[] key = "1A2B3C4D5E6F78901234A5B6C7D8E9F0".getBytes();       
        byte[] username = "bj_simsys".getBytes();  
        IvParameterSpec iv = null; 
          
       // SecretKey secretKey = new SecretKeySpec(key, "DESede"); //密钥默认24位 
        DESedeKeySpec dks = new DESedeKeySpec(key);//密钥32位 
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
		SecretKey securekey = keyFactory.generateSecret(dks);
		
		// DES算法要求有一个可信任的随机数源
		SecureRandom random = new SecureRandom();
		byte seed[] = random.generateSeed(8);//调用 generateSeed 方法来生成给定的种子字节数
	    IvParameterSpec iv = new IvParameterSpec(seed); 
	    
		//encrypt  
        Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding"); 
        cipher.init(Cipher.ENCRYPT_MODE, securekey, iv);  
        byte[] encryptedData = cipher.doFinal(username);  
        System.out.println("encrypt_3des_cbc: " + byteToHexString(encryptedData));
          
		//decrypt  
        cipher.init(Cipher.DECRYPT_MODE, securekey, iv);  
        byte[] decryptPlainText = cipher.doFinal(encryptedData); 
        System.out.println("encrypt_3des_cbc22: " + new String(decryptPlainText));  
	}*/
    
}
DES3ECB.java
package com.dmt.des;

import java.security.Security;

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

/**
 * 3DES加密
 * 
 * @author SHANHY(365384722@QQ.COM)
 * @date 2015-8-18
 */
public class DES3ECB {

	private static final String Algorithm = "DESede"; // 定义 加密算法,可用
														// DES,DESede,Blowfish

	public static String byteToHexString(byte[] bytes) {
        StringBuffer sb = new StringBuffer(bytes.length);
        String sTemp;
        for (int i = 0; i < bytes.length; i++) {
            sTemp = Integer.toHexString(0xFF & bytes[i]);
            if (sTemp.length() < 2)
                sb.append(0);
            sb.append(sTemp.toUpperCase());
        }
        return sb.toString();
    }
	  
	
	/**
	 * 加密方法
	 * 
	 * @param keybyte
	 *            加密密钥,长度为24字节
	 * @param src
	 *            被加密的数据缓冲区(源)
	 * @return
	 * @author SHANHY
	 * @date 2015-8-18
	 */
	public static byte[] encryptMode(byte[] keybyte, byte[] src) {
		try {
			// 生成密钥
			SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);

			// 加密
			Cipher c1 = Cipher.getInstance(Algorithm);
			c1.init(Cipher.ENCRYPT_MODE, deskey);
			return c1.doFinal(src);
		} catch (java.security.NoSuchAlgorithmException e1) {
			e1.printStackTrace();
		} catch (javax.crypto.NoSuchPaddingException e2) {
			e2.printStackTrace();
		} catch (java.lang.Exception e3) {
			e3.printStackTrace();
		}
		return null;
	}

	/**
	 * 解密
	 * 
	 * @param keybyte
	 *            加密密钥,长度为24字节
	 * @param src
	 *            加密后的缓冲区
	 * @return
	 * @author SHANHY
	 * @date 2015-8-18
	 */
	public static byte[] decryptMode(byte[] keybyte, byte[] src) {
		try {
			// 生成密钥
			SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);

			// 解密
			Cipher c1 = Cipher.getInstance(Algorithm);
			c1.init(Cipher.DECRYPT_MODE, deskey);
			return c1.doFinal(src);
		} catch (java.security.NoSuchAlgorithmException e1) {
			e1.printStackTrace();
		} catch (javax.crypto.NoSuchPaddingException e2) {
			e2.printStackTrace();
		} catch (java.lang.Exception e3) {
			e3.printStackTrace();
		}
		return null;
	}

	/**
	 * 转换成十六进制字符串
	 * 
	 * @param b
	 * @return
	 * @author SHANHY
	 * @date 2015-8-18
	 */
	public static String byte2hex(byte[] b) {
		String hs = "";
		String stmp = "";

		for (int n = 0; n < b.length; n++) {
			stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
			if (stmp.length() == 1)
				hs = hs + "0" + stmp;
			else
				hs = hs + stmp;
			if (n < b.length - 1)
				hs = hs + ":";
		}
		return hs.toUpperCase();
	}

	/**
	 * 测试
	 * 
	 * @param args
	 * @author SHANHY
	 * @date 2015-8-18
	 */
	public static void main(String[] args) {
		// 添加新安全算法,如果用JCE就要把它添加进去
		//Security.addProvider(new com.sun.crypto.provider.SunJCE());

		// 24字节的密钥(我们可以取apk签名的指纹的前12个byte和后12个byte拼接在一起为我们的密钥)
		//final byte[] keyBytes = { 0x11, 0x22, 0x4F, 0x58, (byte) 0x88, 0x10, 0x40, 0x38, 0x28, 0x25, 0x79, 0x51, (byte) 0xCB, (byte) 0xDD, 0x55, 0x66, 0x77, 0x29, 0x74, (byte) 0x98, 0x30, 0x40, 0x36, (byte) 0xE2 };
		final String key = "1A2B3C4D5E6F78901234A5B6";
		String username = "bj_simsys";

		System.out.println("加密前的字符串:" + username);

		byte[] encoded = encryptMode(key.getBytes(), username.getBytes());
		System.out.println("加密后:"+byteToHexString(encoded));
		//System.out.println("加密后的字符串:" + new String(encoded));

		byte[] srcBytes = decryptMode(key.getBytes(), encoded);
		System.out.println("解密后的字符串:" + (new String(srcBytes)));
	}

}
Des3ECBUtils.java
package com.dmt.des;

import java.io.UnsupportedEncodingException;

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


/**
 * SecretUtils {3DES加密解密的工具类 }
 * @author William
 * @date 2013-04-19
 */
 public class Des3ECBUtils {
  
    //定义加密算法,有DES、DESede(即3DES)、Blowfish
     private static final String Algorithm = "DESede";    
     private static final String PASSWORD_CRYPT_KEY = "1A2B3C4D5E6F78901234A5B6C7D8E9F01A2B3C4D5E6F78901234A5B6C7D8E9F01A2B3C4D5E6F78901234A5B6C7D8E9F0";
    
    
    /**
      * 加密方法
      * @param src 源数据的字节数组
      * @return 
      */
     public static byte[] encryptMode(byte[] src) {
         try {
             SecretKey deskey = new SecretKeySpec(build3DesKey(PASSWORD_CRYPT_KEY), Algorithm);    //生成密钥
            Cipher c1 = Cipher.getInstance(Algorithm);    //实例化负责加密/解密的Cipher工具类
              c1.init(Cipher.ENCRYPT_MODE, deskey);    //初始化为加密模式
             return c1.doFinal(src);
         } catch (java.security.NoSuchAlgorithmException e1) {
            e1.printStackTrace();
          } catch (javax.crypto.NoSuchPaddingException e2) {
              e2.printStackTrace();
          } catch (java.lang.Exception e3) {
              e3.printStackTrace();
         }
          return null;
     }
   
    
    /**
     * 解密函数
      * @param src 密文的字节数组
      * @return
     */
    public static byte[] decryptMode(byte[] src) {      
         try {
             SecretKey deskey = new SecretKeySpec(build3DesKey(PASSWORD_CRYPT_KEY), Algorithm);
            Cipher c = Cipher.getInstance(Algorithm);
             c.init(Cipher.DECRYPT_MODE, deskey);    //初始化为解密模式
             return c.doFinal(src);
        } catch (java.security.NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (javax.crypto.NoSuchPaddingException e) {
            e.printStackTrace();
         } catch (java.lang.Exception e3) {
           e3.printStackTrace();
        }
       return null;
      }
     
     
     /*
      * 根据字符串生成密钥字节数组 
      * @param keyStr 密钥字符串
      * @return 
      * @throws UnsupportedEncodingException
     */
    public static byte[] build3DesKey(String keyStr) throws UnsupportedEncodingException{
         byte[] key = new byte[24];    //声明一个位的字节数组,默认里面都是0
        byte[] temp = keyStr.getBytes("UTF-8");    //将字符串转成字节数组
        
        /*
          * 执行数组拷贝
          * System.arraycopy(源数组,从源数组哪里开始拷贝,目标数组,拷贝多少位)
          */
         if(key.length > temp.length){
             //如果temp不够位,则拷贝temp数组整个长度的内容到key数组中
             System.arraycopy(temp, 0, key, 0, temp.length);
        }else{
             //如果temp大于位,则拷贝temp数组个长度的内容到key数组中
             System.arraycopy(temp, 0, key, 0, key.length);
         }
       //  System.out.println("11=="+byteToHexString(key));
         return key;
     } 
    
    /**
	 * 功能:将byte[]的字节数组转ASICC码
	 * @param bytes 字节数组
     * @return ASICC码(也是16进制)
	 */
    public static String byteToHexString(byte[] bytes) {
        StringBuffer sb = new StringBuffer(bytes.length);
        String sTemp;
        for (int i = 0; i < bytes.length; i++) {
            sTemp = Integer.toHexString(0xFF & bytes[i]);
            if (sTemp.length() < 2)
                sb.append(0);
            sb.append(sTemp.toUpperCase());
        }
        return sb.toString();
    }
    
    public static void main(String[] args) {
         String msg = "bj_simsys";//3DES加密解密案例
         System.out.println("【加密前】:" + msg);
         
         //加密
         byte[] secretArr = Des3ECBUtils.encryptMode(msg.getBytes());    
        // System.out.println("【加密后】:" + new String(secretArr));
         System.out.println("加密后:"+byteToHexString(secretArr));
         
         //解密
         byte[] myMsgArr = Des3ECBUtils.decryptMode(secretArr);  
        System.out.println("【解密后】:" + new String(myMsgArr));
     }
 }
Des3ECBUtils1.java
package com.dmt.des;

import java.io.UnsupportedEncodingException;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.SecretKeySpec;


/**
 * SecretUtils {3DES加密解密的工具类 }
 * @author William
 * @date 2013-04-19
 */
 public class Des3ECBUtils1 {
  
	 /** 定义加密算法,有DES、DESede(即3DES)、Blowfish*/
     private static final String Algorithm = "DESede";    
     /** 密钥 */
	 private static SecretKey securekey;
    
    /**
      * 加密方法
      * @param src 源数据的字节数组
      * @return 
      */
	public static byte[] encryptMode(String enKey, byte[] src) {
		try {
			DESedeKeySpec dks = new DESedeKeySpec(enKey.getBytes());
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(Algorithm);
			securekey = keyFactory.generateSecret(dks);

			Cipher c1 = Cipher.getInstance(Algorithm); // 实例化负责加密/解密的Cipher工具类
			c1.init(Cipher.ENCRYPT_MODE, securekey); // 初始化为加密模式
			return c1.doFinal(src);
		} catch (java.security.NoSuchAlgorithmException e1) {
			e1.printStackTrace();
		} catch (javax.crypto.NoSuchPaddingException e2) {
			e2.printStackTrace();
		} catch (java.lang.Exception e3) {
			e3.printStackTrace();
		}
		return null;
	}
   
    
	/**
	 * 解密函数
	 * @param src 密文的字节数组
	 * @return
	 */
	public static byte[] decryptMode(String enKey, byte[] src) {
		try {
			DESedeKeySpec dks = new DESedeKeySpec(enKey.getBytes());
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(Algorithm);
			securekey = keyFactory.generateSecret(dks);

			Cipher c = Cipher.getInstance(Algorithm);
			c.init(Cipher.DECRYPT_MODE, securekey); // 初始化为解密模式
			return c.doFinal(src);
		} catch (java.security.NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (javax.crypto.NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (java.lang.Exception e3) {
			e3.printStackTrace();
		}
		return null;
	}
     
	/**
	 * 根据字符串生成密钥字节数组
	 * 
	 * @param keyStr
	 *            密钥字符串
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static byte[] build3DesKey(String keyStr)throws UnsupportedEncodingException {
		byte[] key = new byte[24]; // 声明一个位的字节数组,默认里面都是0
		byte[] temp = keyStr.getBytes("UTF-8"); // 将字符串转成字节数组

		/*
		 * 执行数组拷贝 System.arraycopy(源数组,从源数组哪里开始拷贝,目标数组,拷贝多少位)
		 */
		if (key.length > temp.length) {
			// 如果temp不够位,则拷贝temp数组整个长度的内容到key数组中
			System.arraycopy(temp, 0, key, 0, temp.length);
		} else {
			// 如果temp大于位,则拷贝temp数组个长度的内容到key数组中
			System.arraycopy(temp, 0, key, 0, key.length);
		}
		System.out.println("【十六进制24字节-密钥】:1A2B3C4D5E6F78901234");
		// System.out.println("【ASCII-密钥】:"+byteToHexString(key));

		return key;
	}
    
    //字节转ASICC码
    public static String byteToHexString(byte[] bytes) {
        StringBuffer sb = new StringBuffer(bytes.length);
        String sTemp;
        for (int i = 0; i < bytes.length; i++) {
            sTemp = Integer.toHexString(0xFF & bytes[i]);
            if (sTemp.length() < 2)
                sb.append(0);
            sb.append(sTemp.toUpperCase());
        }
        return sb.toString();
    }
    
    public static void main(String[] args) {
         String msg = "bj_simsys";//3DES加密解密案例
         String key = "1A2B3C4D5E6F78901234A5B6C7D8E9F0";//3DES加密解密案例
         System.out.println("【加密前】:" + msg);
         
         //加密
         byte[] secretArr = Des3ECBUtils1.encryptMode(key, msg.getBytes());    
        // System.out.println("【加密后】:" + new String(secretArr));
         System.out.println("【加密后】:"+byteToHexString(secretArr));
         
         //解密
         byte[] myMsgArr = Des3ECBUtils1.decryptMode(key, secretArr);  
        System.out.println("【解密后】:" + new String(myMsgArr));
     }
 }
DESCryptography.java
package com.dmt.des;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;

public class DESCryptography {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		String content="bj_simsys";
		String key="01234567";
	
		System.out.println("加密前:"+byteToHexString(content.getBytes()));
		byte[] encrypted=DES_CBC_Encrypt(content.getBytes(), key.getBytes());
		System.out.println("加密后:"+byteToHexString(encrypted));
		byte[] decrypted=DES_CBC_Decrypt(encrypted, key.getBytes());
		System.out.println("解密后:"+byteToHexString(decrypted));
 	}

	public static byte[] DES_CBC_Encrypt(byte[] content, byte[] keyBytes){		
		try {
			DESKeySpec keySpec=new DESKeySpec(keyBytes);
			SecretKeyFactory keyFactory=SecretKeyFactory.getInstance("DES");			
			SecretKey key=keyFactory.generateSecret(keySpec);		
			
			Cipher cipher=Cipher.getInstance("DES/CBC/PKCS5Padding");
			cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(keySpec.getKey()));			
			byte[] result=cipher.doFinal(content);
			return result;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			System.out.println("exception:"+e.toString());
		}
		return null;
	}
	
	public static byte[] DES_CBC_Decrypt(byte[] content, byte[] keyBytes){		
		try {
			DESKeySpec keySpec=new DESKeySpec(keyBytes);
			SecretKeyFactory keyFactory=SecretKeyFactory.getInstance("DES");
			SecretKey key=keyFactory.generateSecret(keySpec);
			
			Cipher cipher=Cipher.getInstance("DES/CBC/PKCS5Padding");
			cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(keyBytes));
			byte[] result=cipher.doFinal(content);
			return result;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			System.out.println("exception:"+e.toString());
		}
		return null;
	}
	
	/**
	 * 功能:将byte[]的字节数组转ASICC码
	 * @param bytes 字节数组
     * @return ASICC码(也是16进制)
	 */
	public static String byteToHexString(byte[] bytes) {
        StringBuffer sb = new StringBuffer(bytes.length);
        String sTemp;
        for (int i = 0; i < bytes.length; i++) {
            sTemp = Integer.toHexString(0xFF & bytes[i]);
            if (sTemp.length() < 2)
                sb.append(0);
            sb.append(sTemp.toUpperCase());
        }
        return sb.toString();
    }
	  
	/* private static byte toByte(char c) {
	    byte b = (byte) "0123456789ABCDEF".indexOf(c);
	    return b;
	 }*/
}
DesStringToAscii.java
package com.dmt.des;

import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

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

import com.dmt.util.DecrypTool;

import dmt3des.Arithmetic;

public class DesStringToAscii {
	private static final byte FIX_BYTE=0x00;
	private static final int BUFFER_SIZE = 1024;
	
//	public void encode(InputStream rawMessage, OutputStream encodedMessage) {
//		try {
//		Cipher cipher = Cipher.getInstance(ALGORITHM);
//		cipher.init(Cipher.ENCRYPT_MODE, this.deskey);
//		byte[] buffer = new byte[BUFFER_SIZE];
//		int size = 0;
//		while ((size = rawMessage.read(buffer)) != -1) {
//		if(size
 
  len-8;i--){
//	if(buffer[i]==FIX_BYTE){
//	len--;
//	}else{
//	break;
//	}
//	}
//	return len;
//	}
	///
	private static String toHexUtil(int n){
	        String rt="";
	        switch(n){
	        case 10:rt+="A";break;
	        case 11:rt+="B";break;
	        case 12:rt+="C";break;
	        case 13:rt+="D";break;
	        case 14:rt+="E";break;
	        case 15:rt+="F";break;
	        default:
	            rt+=n;
	        }
	        return rt;
	    }
	    
	    public static String toHex(int n){
	        StringBuilder sb=new StringBuilder();
	        if(n/16==0){
	            return toHexUtil(n);
	        }else{
	            String t=toHex(n/16);
	            int nn=n%16;
	            sb.append(t).append(toHexUtil(nn));
	        }
	        return sb.toString();
	    }
	    
	    public static String parseAscii(String str){
	        StringBuilder sb=new StringBuilder();
	        byte[] bs=str.getBytes();
	        for(int i=0;i
   
   
    Datato.java
    
   
package com.dmt.des;

import java.io.UnsupportedEncodingException;


public class Datato {
	/**
	 * 功能:将byte[]的字节数组转ASICC码
	 * @param bytes 字节数组
     * @return ASICC码(也是16进制)
	 */
    public static String byteToHexASICC(byte[] bytes) {
        StringBuffer sb = new StringBuffer(bytes.length);
        String sTemp;
        for (int i = 0; i < bytes.length; i++) {
            sTemp = Integer.toHexString(0xFF & bytes[i]);
            if (sTemp.length() < 2)
                sb.append(0);
            sb.append(sTemp.toUpperCase());
        }
        return sb.toString();
    }
    //111111111111111111111111111111111111111111111 over
    
    /** 转换数据 */
    private static final char[] HEXDIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
    /**
     * 功能:将byte[]的转换为相应的十六进制字符串
     * @param ba 字节数组
     * @return 十六进制字符串
     */
    public static String bytetohex(byte[] ba, int offset, int length) {
        char[] buf = new char[length * 2];
        int j = 0;
        int k;
        for (int i = offset; i < offset + length; i++) {
            k = ba[i];
            buf[j++] = HEXDIGITS[(k >>> 4) & 0x0F];
            buf[j++] = HEXDIGITS[k & 0x0F];
        }
        return new String(buf);
    }
    //22222222222222222222222222222222222222222222222222222222222222 over
    
    /**
     * 功能:将十六进制字符串转换为字节数组
     * @param hex 十六进制字符串
     * @return 字节数组
     */
    public static byte[] hextobyte(String hex) {
        int len = hex.length();
        byte[] buf = new byte[(len + 1) / 2];
        int i = 0;
        int j = 0;
        if ((len % 2) == 1) {
            buf[j++] = (byte) hexchartoint(hex.charAt(i++));
        }
        while (i < len) {
            buf[j++] = (byte) ((hexchartoint(hex.charAt(i++)) << 4) | hexchartoint(hex.charAt(i++)));
        }
        return buf;
    }
    //33333333333333333333333333333333333333333333333333333 over
    
    /**
     * 功能:将十六进制的char转换为十进制的int值
     * @param ch 十六进制的char
     * @return 十进制 int值
     */
    public static int hexchartoint(char ch) {
        if (ch >= '0' && ch <= '9') {
            return ch - '0';
        }
        if (ch >= 'A' && ch <= 'F') {
            return ch - 'A' + 10;
        }
        if (ch >= 'a' && ch <= 'f') {
            return ch - 'a' + 10;
        }
        throw new IllegalArgumentException("invalid hex digit '" + ch + "'");
    }
    //444444444444444444444444444444444444444444444444444444444444 over
    
    /**
     * 功能:字符串转换为十六进制ASCII
     * @param str 普通字符串,如:bj_simsys
     * @return 十六进制ASCII
     */
    public static String parseAscii(String str){
        StringBuilder sb=new StringBuilder();
        byte[] bs=str.getBytes();
        for(int i=0;i
    
      temp.length) {
			// 如果temp不够位,则拷贝temp数组整个长度的内容到key数组中
			System.arraycopy(temp, 0, key, 0, temp.length);
		} else {
			// 如果temp大于位,则拷贝temp数组个长度的内容到key数组中
			System.arraycopy(temp, 0, key, 0, key.length);
		}
		System.out.println("【十六进制24字节-密钥】:1A2B3C4D5E6F78901234");
		// System.out.println("【ASCII-密钥】:"+byteToHexString(key));

		return key;
	}
	
	
	//测试
	public static void main(String[] args) {
		final String key = "1A2B3C4D5E6F78901234A5B6";
		String username = "bj_simsys";

		System.out.println("加密前的字符串:" + username);

		byte[] encoded = DES3ECB.encryptMode(key.getBytes(), username.getBytes());
		System.out.println("加密后:"+DES3ECB.byte2hex(encoded));
	}
}
    
网友评论