Java实现国密算法SM4/SM3详解及封装工具类(附对称/非对称加密对比)

Java实现国密算法SM4/SM3详解及封装工具类(附对称/非对称加密对比)

1. 加密算法基础概念

(1)对称加密 vs 非对称加密

特性对称加密(如SM4/AES)非对称加密(如SM2/RSA)
密钥加密/解密使用相同密钥公钥加密,私钥解密
速度快(适合大数据加密)慢(适合小数据加密)
用途数据加密存储/传输数字签名、密钥交换
典型算法SM4、AES、DESSM2、RSA、ECC

(2)国密算法简介

  • SM1:对称加密(硬件实现,不公开)
  • SM2:基于ECC的非对称加密(替代RSA)
  • SM3:摘要算法(替代SHA-256)
  • SM4:对称加密(替代AES)

2. 完整工具类封装

(1)SM4加密工具类

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.*;
import java.util.Base64;

public class Sm4Utils {
    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    /**
     * 生成SM4密钥(16字节)
     */
    public static byte[] generateKey() throws Exception {
        KeyGenerator kg = KeyGenerator.getInstance("SM4", "BC");
        kg.init(128); // 128位密钥
        return kg.generateKey().getEncoded();
    }

    /**
     * SM4加密(CBC模式)
     * @param data 明文
     * @param key  16字节密钥
     * @param iv   16字节初始化向量
     */
    public static String encrypt(String data, byte[] key, byte[] iv) throws Exception {
        Cipher cipher = Cipher.getInstance("SM4/CBC/PKCS5Padding", "BC");
        SecretKeySpec keySpec = new SecretKeySpec(key, "SM4");
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
        byte[] encrypted = cipher.doFinal(data.getBytes());
        return Base64.getEncoder().encodeToString(encrypted);
    }

    /**
     * SM4解密
     */
    public static String decrypt(String encryptedData, byte[] key, byte[] iv) throws Exception {
        Cipher cipher = Cipher.getInstance("SM4/CBC/PKCS5Padding", "BC");
        SecretKeySpec keySpec = new SecretKeySpec(key, "SM4");
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
        byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
        return new String(decrypted);
    }
}

(2)SM3摘要工具类

import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.util.encoders.Hex;

public class Sm3Utils {
    /**
     * 生成SM3摘要(32字节)
     */
    public static String hash(String data) {
        SM3Digest digest = new SM3Digest();
        byte[] bytes = data.getBytes();
        digest.update(bytes, 0, bytes.length);
        
        byte[] hash = new byte[digest.getDigestSize()];
        digest.doFinal(hash, 0);
        return Hex.toHexString(hash);
    }

    /**
     * 文件摘要计算
     */
    public static String hashFile(byte[] fileData) {
        SM3Digest digest = new SM3Digest();
        digest.update(fileData, 0, fileData.length);
        
        byte[] hash = new byte[digest.getDigestSize()];
        digest.doFinal(hash, 0);
        return Hex.toHexString(hash);
    }
}

(3)SM2非对称加密工具类(需BC支持)

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.*;
import java.security.spec.*;

public class Sm2Utils {
    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    /**
     * 生成SM2密钥对
     */
    public static KeyPair generateKeyPair() throws Exception {
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", "BC");
        kpg.initialize(SM2Params.DOMAIN_PARAMS); // 使用SM2预设参数
        return kpg.generateKeyPair();
    }

    /**
     * 公钥加密
     */
    public static byte[] encrypt(byte[] data, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance("SM2", "BC");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return cipher.doFinal(data);
    }

    /**
     * 私钥解密
     */
    public static byte[] decrypt(byte[] encryptedData, PrivateKey privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance("SM2", "BC");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return cipher.doFinal(encryptedData);
    }
}

3. 完整使用示例

(1)SM4示例

public static void main(String[] args) throws Exception {
    // 生成密钥和IV
    byte[] key = Sm4Utils.generateKey();
    byte[] iv = new byte[16]; // 实际项目应使用SecureRandom生成
    
    // 加密
    String encrypted = Sm4Utils.encrypt("Hello SM4", key, iv);
    System.out.println("加密结果: " + encrypted);
    
    // 解密
    String decrypted = Sm4Utils.decrypt(encrypted, key, iv);
    System.out.println("解密结果: " + decrypted);
}

(2)SM3示例

String hash = Sm3Utils.hash("Hello SM3");
System.out.println("SM3摘要: " + hash); // 输出32字节十六进制字符串

(3)SM2示例

KeyPair keyPair = Sm2Utils.generateKeyPair();
byte[] encrypted = Sm2Utils.encrypt("Hello SM2".getBytes(), keyPair.getPublic());
byte[] decrypted = Sm2Utils.decrypt(encrypted, keyPair.getPrivate());
System.out.println("SM2解密: " + new String(decrypted));

4. 性能与安全建议

(1)算法选择指南

场景推荐算法
大数据加密SM4(对称加密)
密钥传输/数字签名SM2(非对称加密)
密码存储/完整性校验SM3(摘要算法)

(2)最佳实践

  1. 密钥管理
    • 对称加密密钥需定期更换
    • 非对称加密私钥必须安全存储(HSM/KeyStore)
  2. 模式选择
    • SM4优先选CBC或GCM模式(需随机IV)
  3. 摘要增强
    • 密码存储应结合盐值(Salt)+多次哈希

5. 总结

本文完整实现了:

  1. SM4对称加密工具类(支持密钥生成/CBC模式加解密)
  2. SM3摘要工具类(支持字符串/文件摘要)
  3. SM2非对称加密工具类(密钥对生成/加解密)
  4. 详细对比了对称/非对称加密特性

📌 提示:生产环境建议使用国密合规的硬件加密机进行密钥管理。

如果觉得有帮助,请点赞收藏支持! 🔐

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

遥不可及~~斌

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

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

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

打赏作者

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

抵扣说明:

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

余额充值