import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.security.Security;

public class SM4Demo {

    static {
        // 添加 BouncyCastle 安全提供者
        Security.addProvider(new BouncyCastleProvider());
    }

    /**
     * SM4 加密
     * @param key 16字节密钥
     * @param plainText 明文
     * @return 密文(十六进制字符串)
     */
    public static String encrypt(byte[] key, String plainText) throws Exception {
        SecretKeySpec secretKey = new SecretKeySpec(key, "SM4");
        Cipher cipher = Cipher.getInstance("SM4/ECB/PKCS5Padding", "BC");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] encrypted = cipher.doFinal(plainText.getBytes());
        return bytesToHex(encrypted);
    }

    /**
     * SM4 解密
     * @param key 16字节密钥
     * @param cipherText 十六进制密文
     * @return 明文字符串
     */
    public static String decrypt(byte[] key, String cipherText) throws Exception {
        SecretKeySpec secretKey = new SecretKeySpec(key, "SM4");
        Cipher cipher = Cipher.getInstance("SM4/ECB/PKCS5Padding", "BC");
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] decrypted = cipher.doFinal(hexToBytes(cipherText));
        return new String(decrypted);
    }

    // 字节数组转十六进制字符串
    private static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02X", b));
        }
        return sb.toString();
    }

    // 十六进制字符串转字节数组
    private static byte[] hexToBytes(String hex) {
        int len = hex.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
                    + Character.digit(hex.charAt(i + 1), 16));
        }
        return data;
    }

    public static void main(String[] args) throws Exception {
        // 16 字节密钥(128位)
        byte[] key = "1234567890123456".getBytes();  // 必须是16字节

        String plainText = "Hello, SM4! 国密算法测试。";

        System.out.println("原文: " + plainText);

        // 加密
        String cipherText = encrypt(key, plainText);
        System.out.println("加密: " + cipherText);

        // 解密
        String decryptedText = decrypt(key, cipherText);
        System.out.println("解密: " + decryptedText);
    }
}

更多推荐