3DES加解密Java实现

Encription

package bbg.secret;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.io.*;
import java.security.Key;
import java.security.SecureRandom;

public class Encription {

    /**
     * 16进制字符数组
     */
    private static final char[] HEX_CHARS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
    /**
     * 算法DESede
     */
    private final static String DESEDE_ALGORITHM_NAME = "DESede";

    private static BouncyCastleProvider provider = new BouncyCastleProvider();

    private final static byte[] DEFAULT_IVPARAMS = new byte[8];
    /**
     * instance参数
     */
    private final static String INSTANCEPARAM = "DESede/CBC/PKCS5Padding";

    public static void main(String[] args) throws Exception {
        String content = readFileToString("E:/工作文件目录/输出测试/蚂蚁测试/兴全蚂蚁测试/SDK_SWHYA001_F003_20210513.txt", "UTF-8");
        Cipher cipher = createCipher(true, "ASDFGqwert012345678901234567890123456789012345678913");
        byte[] result = cipher.doFinal(content.getBytes("UTF-8"));
        saveStringToFile("F://test1.txt", byteArrayToHexStr(result), "UTF-8");
    }

    private static Cipher createCipher(boolean isEncrypt, String key) throws Exception {
        // 解码16进制转化为2进制,两位转1位,对于不在十六进制数的转为0
        byte[] input = HexCodec.decode(key);
        // 从原始密钥数据创建DESKeySpec对象
        DESedeKeySpec keySpec = new DESedeKeySpec(input);
        //创建一个密匙工厂,然后用它把DESKeySpec转换成一个SecretKey对象
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DESEDE_ALGORITHM_NAME, provider);
        SecretKey secretKey = keyFactory.generateSecret(keySpec);
        // 根据模式判断加密还是解密
        int mode = isEncrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE;
        // 创建cipher
        Cipher cipher = Cipher.getInstance(INSTANCEPARAM);
        // DES算法要求有一个可信任的随机数源,两种方式都可以
        IvParameterSpec iv = new IvParameterSpec(DEFAULT_IVPARAMS);
        SecureRandom sr = new SecureRandom();
        cipher.init(mode, secretKey, sr);
        return cipher;

    }

    private static String readFileToString(String fileName, String encoding) {
        File file = new File(fileName);
        Long filelength = file.length();
        byte[] filecontent = new byte[filelength.intValue()];
        FileInputStream in = null;
        try {
            in = new FileInputStream(file);
            in.read(filecontent);
            return new String(filecontent, encoding);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private static void saveStringToFile(String fileName, String content, String encoding) {
        Writer writer = null;
        try {
            writer = new OutputStreamWriter(new FileOutputStream(fileName), encoding);
            writer.write(content);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 二进制转化为十六进制
     *
     * @param byteArray
     * @return
     */
    private static String byteArrayToHexStr(byte[] byteArray) {
        if (byteArray == null) {
            return null;
        }
        char[] hexChars = new char[byteArray.length * 2];
        for (int j = 0; j < byteArray.length; j++) {
            int v = byteArray[j] & 0xFF;
            hexChars[j * 2] = HEX_CHARS[v >>> 4];
            hexChars[j * 2 + 1] = HEX_CHARS[v & 0x0F];
        }
        return new String(hexChars);
    }
}

Hex

package bbg.secret;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;

/**
 * 16进制编解码器
 *
 * @author
 * @date 2021/10/26 10:29
 * @since 1.0.0
 */
public final class HexCodec {

    /**
     * 编码表数组
     */
    final static byte[] ENCODINGTABLE = {
            (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7',
            (byte) '8', (byte) '9', (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f'
    };

    /**
     * 解码表数组
     */
    final static byte[] DECODINGTABLE = new byte[128];

    static {
        for (int i = 0; i < ENCODINGTABLE.length; i++) {
            DECODINGTABLE[ENCODINGTABLE[i]] = (byte) i;
        }

        DECODINGTABLE['A'] = DECODINGTABLE['a'];
        DECODINGTABLE['B'] = DECODINGTABLE['b'];
        DECODINGTABLE['C'] = DECODINGTABLE['c'];
        DECODINGTABLE['D'] = DECODINGTABLE['d'];
        DECODINGTABLE['E'] = DECODINGTABLE['e'];
        DECODINGTABLE['F'] = DECODINGTABLE['f'];
    }

    private HexCodec() {
    }

    /**
     * 对字节数组进行编码
     *
     * @param data 原始字节数组
     * @return
     */
    public static byte[] encode(byte[] data) {
        return encode(data, 0, data.length);
    }

    /**
     * 对字节数组进行编码,指定偏移量和长度
     *
     * @param data   原始字节数组
     * @param off    偏移量
     * @param length 长度
     * @return
     */
    public static byte[] encode(byte[] data, int off, int length) {
        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
        try {
            encode(data, off, length, bOut);
        } catch (IOException e) {
            throw new RuntimeException("编码发生异常: " + e);
        }

        return bOut.toByteArray();
    }

    /**
     * 对数据进行编码,并输出到指定的输出流
     *
     * @param data   原始数据
     * @param off    偏移量
     * @param length 需编码数据长度
     * @param out    输出流
     * @return 编码后的数据长度
     * @throws IOException
     */
    public static int encode(byte[] data, int off, int length, OutputStream out) throws IOException {
        for (int i = off; i < (off + length); i++) {
            int v = data[i] & 0xff;

            out.write(ENCODINGTABLE[(v >>> 4)]);
            out.write(ENCODINGTABLE[v & 0xf]);
        }

        return length * 2;
    }

    private static boolean ignore(char c) {
        return (c == '\n' || c == '\r' || c == '\t' || c == ' ');
    }

    /**
     * 解码16进制字节数组,忽略空白字符
     *
     * @param data   加密后的字节数据
     * @param off    偏移量
     * @param length 需解密的字节长度
     * @param out    输出流
     * @return 输出数据长度
     * @throws IOException
     */
    public static int decode(byte[] data, int off, int length, OutputStream out) throws IOException {
        byte b1, b2;
        int outLen = 0;

        int end = off + length;

        while (end > off) {
            if (!ignore((char) data[end - 1])) {
                break;
            }

            end--;
        }

        int i = off;
        while (i < end) {
            while (i < end && ignore((char) data[i])) {
                i++;
            }

            b1 = DECODINGTABLE[data[i++]];

            while (i < end && ignore((char) data[i])) {
                i++;
            }

            b2 = DECODINGTABLE[data[i++]];

            out.write((b1 << 4) | b2);

            outLen++;
        }

        return outLen;
    }


    /**
     * 解码16进制字符串,忽略空白字符
     *
     * @param data 加密后的16进制字符串
     * @param out  输出流
     * @return 输出数据长度
     * @throws IOException
     */
    public static int decode(String data, OutputStream out) throws IOException {
        byte b1, b2;
        int length = 0;

        int end = data.length();

        while (end > 0) {
            if (!ignore(data.charAt(end - 1))) {
                break;
            }

            end--;
        }

        int i = 0;
        while (i < end) {
            while (i < end && ignore(data.charAt(i))) {
                i++;
            }

            b1 = DECODINGTABLE[data.charAt(i++)];

            while (i < end && ignore(data.charAt(i))) {
                i++;
            }

            b2 = DECODINGTABLE[data.charAt(i++)];

            out.write((b1 << 4) | b2);

            length++;
        }

        return length;
    }

    /**
     * 解码16进制字节数组,并返回解密后的字节数据
     *
     * @param data
     * @return
     */
    public static byte[] decode(byte[] data) {
        ByteArrayOutputStream bOut = new ByteArrayOutputStream();

        try {
            decode(data, 0, data.length, bOut);
        } catch (IOException e) {
            throw new RuntimeException("解码发生异常: " + e);
        }

        return bOut.toByteArray();
    }

    /**
     * 对字符串进行解码
     *
     * @param data 原始字符串
     * @return
     */
    public static byte[] decode(String data) {
        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
        try {
            decode(data, bOut);
        } catch (IOException e) {
            throw new RuntimeException("exception decoding Hex string: " + e);
        }

        return bOut.toByteArray();
    }
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值