3DES加密算法32个字节

简介

最近开发的一个项目,使用到了3DES加密算法,加密socket服务端和客户端通信的报文,因为加密秘钥是32个字节,结果折腾了一番,现在记录下来分享!

1、Des3EncryptUtils.java

package des3;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
/**
 * 3DES加密工具类
 * @author QiaoZhenwu
 */
public class Des3EncryptUtils {
    /** 密钥 */
    private SecretKey securekey;
    /**
     * 功能:算法中需要通过秘钥的字节数组来得到加密用的key
     * @param key  秘钥的字节数组
     */
    public void setKey(byte[] key) {
        try {
            DESedeKeySpec dks = new DESedeKeySpec(key);
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
            securekey = keyFactory.generateSecret(dks);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
    /**
     * 功能:对明文进行加密
     * @param byteS  明文对应的字节数组
     * @return 密文对应的字节数组
     */
    public byte[] get3DesEncCode(byte[] byteS) {
        byte[] byteFina = null;
        Cipher cipher;
        try {
            cipher = Cipher.getInstance("DESede/ECB/NoPadding");    //算法/分组模式/填充模式
            cipher.init(Cipher.ENCRYPT_MODE, securekey);
            byteFina = cipher.doFinal(byteS);
        } catch (Exception e) {
          System.out.println(e.getMessage());
        } finally {
            cipher = null;
        }
        return byteFina;
    }
    /**
     * 功能:对密文进行解密
     * @param byteD  密文对应的字节数组
     * @return 明文对应的字节数组
     */
    public byte[] get3DesDesCode(byte[] byteD) {
        Cipher cipher;
        byte[] byteFina = null;
        try {
            cipher = Cipher.getInstance("DESede/ECB/NoPadding");
            cipher.init(Cipher.DECRYPT_MODE, securekey);
            byteFina = cipher.doFinal(byteD);
        } catch (Exception e) {
          System.out.println(e.getMessage());
        } finally {
            cipher = null;
        }
        return byteFina;
    }
}

2、HexUtils.java

package des3;

/**
 * 十六进制帮助类
 * @author jacky
 */
public class HexUtils {
    /** 转换数据 */
    private static final char[] HEXDIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
    /**
     * toString(控制长度的将byte[]的转换为相应的十六进制String表示)
     */
    public static String toString(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);
    }
    /**
     * 功能:将byte[]的转换为相应的十六进制字符串
     * @param ba 字节数组
     * @return 十六进制字符串
     */
    public static String toString(byte[] ba) {
        return toString(ba, 0, ba.length);
    }
    /**
     *  功能:将十六进制字符串转换为字节数组
     * @param hex 十六进制字符串
     * @return 字节数组
     */
    public static byte[] fromString(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) fromDigit(hex.charAt(i++));
        }
        while (i < len) {
            buf[j++] = (byte) ((fromDigit(hex.charAt(i++)) << 4) | fromDigit(hex.charAt(i++)));
        }
        return buf;
    }
    /**
     * fromDigit(将十六进制的char转换为十进制的int值)
     */
    public static int fromDigit(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 + "'");
    }
}

3、Des3Utils.java

package des3;

/**
 * 3DES加解密主类,加解密调用内部的方法
 * @author QiaoZhenwu
 *
 */
public class Des3Utils {
     /**
     * dec:(解密).
     * @param key 密钥
     * @param content 密文内容 16位
     * @return 返回结果:String
     */
    public static String decryption(String key, String content) {
        Des3EncryptUtils des = new Des3EncryptUtils();
        String enKey = "";//最终解密秘钥 48位
        String enContent = "";//解密内容
        if(key.length() <= 32){
          enKey = (key + key).substring(0, 48);
        }else if(key.length() >= 48){
          enKey = key.substring(0, 48);
        }
        if(content.length() == 16){
          enContent = content;
        }else{
          if(content.length() > 16){
              throw new RuntimeException("the encrypt content length more than 16");
          }else if(content.length() < 16){
              throw new RuntimeException("the encrypt content length less than 16");
          }
        }
        des.setKey(enKey.getBytes());
        byte[] get3DesDesCode = des.get3DesDesCode(HexUtils.fromString(enContent));
        return HexUtils.toString(get3DesDesCode).trim();
    }
    
    
    /**
     * dec:(加密).
     * @param key 密钥
     * @param content  明文内容 为16位十六进制字符串
     * @return 返回结果:String
     */
    public static String encryption(String key, String content) {
        Des3EncryptUtils des = new Des3EncryptUtils();
        String enKey = "";//最终加密秘钥48位
        String enContent = "";//加密内容
        if(key.length() <= 32){
          enKey = (key + key).substring(0, 48);
        }else if(key.length() >= 48){
          enKey = key.substring(0, 48);
        }
        if(content.length() == 16){
          enContent = content;
        }else{
          if(content.length() > 16){
              throw new RuntimeException("the encrypt content length more than 16");
          }else if(content.length() < 16){
              throw new RuntimeException("the encrypt content length less than 16");
          }
        }
        des.setKey(enKey.getBytes());
        byte[] bye = des.get3DesEncCode(HexUtils.fromString(enContent));
        return HexUtils.toString(bye).trim();
    }
    
    public static void main(String[] args) {
        String str = encryption("12345678123456781234567812345678", "06111111FFFFFFFF");
        System.out.println("加密后的密文为====="+str);
    }
}
原文地址:https://www.cnblogs.com/520playboy/p/6291411.html