欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

3DES加解密Java实现

程序员文章站 2024-03-14 13:28:52
...

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();
    }
}