SM4国密算法加解密(16进制,base符串)

时间:2025-05-09 16:49:56

1、引入相关jar包

<dependency>
    <groupId></groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.7.12</version>
</dependency>

2、SM4工具类

package com.xxx.xxx.util.sm4;

import cn.hutool.core.util.CharsetUtil;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.symmetric.SM4;
import java.io.IOException;

/**
 * Sm4 加密解密ECB模式,PKCS5Padding补码方式
 */
public class SM4Utils {
   //key必须是16字节,即128位
//   public static String key ;

    public SM4Utils() {
    }

    //加密为16进制,也可以加密成base64/字节数组
    public static String encryptSm4(String plaintext,String key) {
        SM4 sm4 = new SM4(Mode.ECB, Padding.PKCS5Padding, key.getBytes());
        return sm4.encryptBase64(plaintext);
    }

    //解密
    public static String decryptSm4(String ciphertext,String key) {
        SM4 sm4 = new SM4(Mode.ECB, Padding.PKCS5Padding, key.getBytes());
        return sm4.decryptStr(ciphertext, CharsetUtil.CHARSET_UTF_8);
    }


    public static void main(String[] args) throws IOException {
        String plainText = "{\n" +
                "\t\"Name\": \"张三\",\n" +
                "\t\"idCardNum\": \"XXXXXXX\",\n" +
                "\t\"nation\": \"汉\",\n" +
                "\t\"address\": \"xx省xx县\",\n" +
                "\t\"headImage\": \"data:image/jpeg;base64,xxxxxxxxxx\",\n" +
                "\t\"grantOrg\": \"xx县\",\n" +
                "\t\"startDate\": \"2019-01-30\",\n" +
                "\t\"expiryDate\": \"2029-01-30\",\n" +
                "}";
        SM4Utils sm4 = new SM4Utils();
        String key = "975C7238C3824FB0";

        System.out.println("ECB模式加密");
        String cipherText = sm4.encryptSm4(plainText,key);
        System.out.println("密文: " + cipherText);
        System.out.println();

        System.out.println("ECB模式解密");
        String plainText1 = sm4.decryptSm4(cipherText,key);
        System.out.println("明文: " + plainText1);
        System.out.println();
    }
}

3、源码解析

可以根据自己的需要,选择加密算法模式,加密模式如下:

package cn.hutool.crypto;

/**
 * 模式
 *
 * <p>
 * 加密算法模式,是用来描述加密算法(此处特指分组密码,不包括流密码,)在加密时对明文分组的模式,它代表了不同的分组方式
 *
 * @author Looly
 * @see <a href="/javase/7/docs/technotes/guides/security/#Cipher"> Cipher章节</a>
 * @since 3.0.8
 */
public enum Mode {
	/**
	 * 无模式
	 */
	NONE,
	/**
	 * 密码分组连接模式(Cipher Block Chaining)
	 */
	CBC,
	/**
	 * 密文反馈模式(Cipher Feedback)
	 */
	CFB,
	/**
	 * 计数器模式(A simplification of OFB)
	 */
	CTR,
	/**
	 * Cipher Text Stealing
	 */
	CTS,
	/**
	 * 电子密码本模式(Electronic CodeBook)
	 */
	ECB,
	/**
	 * 输出反馈模式(Output Feedback)
	 */
	OFB,
	/**
	 * Propagating Cipher Block
	 */
	PCBC
}

可以根据自己的需要,选择补码方式,补码方式如下:

package cn.hutool.crypto;

/**
 * 补码方式
 *
 * <p>
 * 补码方式是在分组密码中,当明文长度不是分组长度的整数倍时,需要在最后一个分组中填充一些数据使其凑满一个分组的长度。
 *
 * @author Looly
 * @see <a href="/javase/7/docs/technotes/guides/security/#Cipher"> Cipher章节</a>
 * @since 3.0.8
 */
public enum Padding {
	/**
	 * 无补码
	 */
	NoPadding,
	/**
	 * 0补码,即不满block长度时使用0填充
	 */
	ZeroPadding,
	/**
	 * This padding for block ciphers is described in 5.2 Block Encryption Algorithms in the W3C's "XML Encryption Syntax and Processing" document.
	 */
	ISO10126Padding,
	/**
	 * Optimal Asymmetric Encryption Padding scheme defined in PKCS1
	 */
	OAEPPadding,
	/**
	 * The padding scheme described in PKCS #1, used with the RSA algorithm
	 */
	PKCS1Padding,
	/**
	 * The padding scheme described in RSA Laboratories, "PKCS #5: Password-Based Encryption Standard," version 1.5, November 1993.
	 */
	PKCS5Padding,
	/**
	 * The padding scheme defined in the SSL Protocol Version 3.0, November 18, 1996, section 5.2.3.2 (CBC block cipher)
	 */
	SSL3Padding
}

其他源码:加密算法SM4实现对称加密算法SymmetricCrypto需要的可以自己学习下源码!