sm4加解密以及随机生成密钥

字节数组处理工具类

public class ByteUtils {
    private static final char[] HEX_CHARS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e',
            'f' };

    private ByteUtils() {
        // Utility class
    }

    public static byte[] fromHexString(String s) {
        int len = s.length();
        //
        // // Data length must be even
        // if (len % 2 != 0) {
        // throw new IllegalArgumentException("Hex string has an odd number of
        // characters");
        // }

        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));
        }
        return data;
    }



    public static String toHexString(byte[] input) {
        StringBuilder sb = new StringBuilder();
        for (byte b : input) {
            sb.append(HEX_CHARS[(b >>> 4) & 0x0f]);
            sb.append(HEX_CHARS[b & 0x0f]);
        }
        return sb.toString();
    }


    public static String toHexString(byte[] input, String prefix, String separator) {
        StringBuilder sb = new StringBuilder(prefix);
        for (int i = 0; i < input.length; i++) {
            sb.append(HEX_CHARS[(input[i] >>> 4) & 0x0f]);
            sb.append(HEX_CHARS[input[i] & 0x0f]);
            if (i < input.length - 1) {
                sb.append(separator);
            }
        }
        return sb.toString();
    }
}

随机生成十六进制密钥

// 生成 SM4 密钥的方法
    public static String generateSM4Key() {
        // 定义一个 128 位的字节数组
        byte[] keyBytes = new byte[16];

        // 使用 SecureRandom 生成随机密钥
        SecureRandom secureRandom = new SecureRandom();
        secureRandom.nextBytes(keyBytes);

        // 将字节数组转换为十六进制字符串
        StringBuilder sb = new StringBuilder();
        for (byte b : keyBytes) {
            // 使用 Integer.toHexString() 方法将字节转换为十六进制字符串
            sb.append(String.format("%02x", b & 0xff));
        }

        // 返回生成的密钥
        return sb.toString();
    }

//    public static void main(String[] args) {
//        // 生成 SM4 密钥并打印
//        String sm4Key = generateSM4Key();
//        System.out.println("Generated SM4 Key: " + sm4Key);
//    }

sm4工具类

public class Sm4Utils {
    static {
        Security.addProvider(new BouncyCastleProvider());
    }
    private static final String ENCODING = "UTF-8";
    public static final String ALGORIGTHM_NAME = "SM4";
    public static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS7Padding";
    public static final int DEFAULT_KEY_SIZE = 128;

    private static Cipher generateEcbCipher(String algorithmName, int mode, byte[] key) throws Exception {
        Cipher cipher = Cipher.getInstance(algorithmName, "BC");
        Key sm4Key = new SecretKeySpec(key, ALGORIGTHM_NAME);
        cipher.init(mode, sm4Key);
        return cipher;
    }

    public static byte[] generateKey(String keyString) throws Exception {
        // Use SHA-256 to hash the string and then take first 128 bits (16 bytes)
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        byte[] hash = digest.digest(keyString.getBytes(StandardCharsets.UTF_8));
        byte[] key = new byte[16];
        System.arraycopy(hash, 0, key, 0, 16);
        return key;
    }

    public static String encryptEcb(String key, String paramStr, String charset) throws Exception {
        String cipherText = "";
        if (null != paramStr && !"".equals(paramStr)) {
            byte[] keyData = generateKey(key);
            charset = charset.trim();
            if (charset.length() <= 0) {
                charset = ENCODING;
            }
            byte[] srcData = paramStr.getBytes(charset);
            byte[] cipherArray = encryptEcbPadding(keyData, srcData);
            cipherText = ByteUtils.toHexString(cipherArray);
        }

        return cipherText;
    }

    public static byte[] encryptEcbPadding(byte[] key, byte[] data) throws Exception {
        Cipher cipher = generateEcbCipher("SM4/ECB/PKCS7Padding", Cipher.ENCRYPT_MODE, key);
        byte[] bs = cipher.doFinal(data);
        return bs;
    }

    public static String decryptEcb(String key, String cipherText, String charset) throws Exception {
        String decryptStr = "";
        byte[] keyData = generateKey(key);
        byte[] cipherData = ByteUtils.fromHexString(cipherText);
        byte[] srcData = decryptEcbPadding(keyData, cipherData);
        charset = charset.trim();
        if (charset.length() <= 0) {
            charset = ENCODING;
        }

        decryptStr = new String(srcData, charset);
        return decryptStr;
    }

    public static byte[] decryptEcbPadding(byte[] key, byte[] cipherText) throws Exception {
        Cipher cipher = generateEcbCipher("SM4/ECB/PKCS7Padding", Cipher.DECRYPT_MODE, key);
        return cipher.doFinal(cipherText);
    }

    //测试加解密
    public static void main(String[] args) {
        try {
            String enpwd = "";//已加密数据
            String json = "";//需要加密数据
            String key = "";//这里填生成的十六进制密钥
//            String cipher = encryptEcb(key, json, ENCODING);//加密
//            System.out.println(cipher);
            System.out.println(decryptEcb(key, enpwd, ENCODING));//解密
        } catch (Exception var5) {
            var5.printStackTrace();
        }

    }
}

pom

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15to18</artifactId>
    <version>1.68</version>//可根据情况修改
</dependency>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WAZYY0619

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值