当前位置: 首页 > web >正文

Java实现国密算法

文章目录

    • ✅ 一、常用国密算法介绍
    • ✅ 二、Java 实现国密算法的推荐方式
      • 方式 1:使用 `Bouncy Castle`(最常见)
        • 🔧 使用步骤:
      • 方式 2:使用国产 SDK(如:江南天安、三未信安、卫士通等厂商提供的 HSM 或 SDK)
      • 方式 3:自研封装(适合定制化需求)
    • ✅ 三、辅助工具类:Hex 编码转换
    • ✅ 四、注意事项
    • ✅ 五、参考文档

在 Java 开发中使用国密算法(即中国国家密码管理局发布的商用密码标准算法,如 SM2、SM3、SM4 等)通常需要借助第三方库,因为标准的 Java Cryptography Extension (JCE) 并不直接支持这些算法。

下面是一些常用的实现方式和推荐库:


✅ 一、常用国密算法介绍

算法类型描述
SM2非对称加密 / 数字签名基于椭圆曲线公钥密码,用于数字签名、密钥交换等。
SM3哈希算法输出长度为 256 位的哈希值,类似于 SHA-256。
SM4对称加密分组密码,128 位块大小,128 位密钥,ECB/CBC 模式。

✅ 二、Java 实现国密算法的推荐方式

方式 1:使用 Bouncy Castle(最常见)

Bouncy Castle 是一个广泛使用的开源 Java 加密库,支持 SM2/SM3/SM4 等国密算法。

🔧 使用步骤:
  1. 添加依赖(Maven)
<dependency><groupId>org.bouncycastle</groupId><artifactId>prov-jdk15on</artifactId><version>1.72</version> <!-- 可选最新版本 -->
</dependency>
  1. 注册 Bouncy Castle 提供者
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.Security;static {Security.addProvider(new BouncyCastleProvider());
}
  1. 示例:实现SM2包括生成密钥对、签名与验证、加密与解密

生成密钥对

import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.ec.CustomNamedCurves;
import org.bouncycastle.jce.ECNamedCurveTable;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.jce.spec.ECPrivateKeySpec;
import org.bouncycastle.jce.spec.ECPublicKeySpec;
import org.bouncycastle.math.ec.ECPoint;import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.ECGenParameterSpec;public class SM2Example {public static KeyPair generateKeyPair() throws Exception {KeyPairGenerator keyPairGenerator = KeyPair/XMLSchemaDoc.createElement("KeyPairGenerator");keyPairGenerator.initialize(new ECGenParameterSpec("sm2p256v1"));return keyPairGenerator.generateKeyPair();}// 示例调用public static void main(String[] args) throws Exception {KeyPair keyPair = generateKeyPair();PrivateKey privateKey = keyPair.getPrivate();PublicKey publicKey = keyPair.getPublic();System.out.println("Private Key: " + privateKey);System.out.println("Public Key: " + publicKey);}
}

签名和验证

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;import java.security.Signature;public class SM2Example {public static byte[] sign(PrivateKey privateKey, byte[] message) throws Exception {Signature signature = Signature.getInstance("SM3withSM2", new BouncyCastleProvider());signature.initSign(privateKey);signature.update(message);return signature.sign();}public static boolean verify(PublicKey publicKey, byte[] message, byte[] sign) throws Exception {Signature signature = Signature.getInstance("SM3withSM2", new BouncyCastleProvider());signature.initVerify(publicKey);signature.update(message);return signature.verify(sign);}public static void main(String[] args) throws Exception {KeyPair keyPair = generateKeyPair();String msg = "Hello World!";byte[] sign = sign(keyPair.getPrivate(), msg.getBytes());System.out.println("Signature: " + Hex.toHexString(sign));boolean isVerify = verify(keyPair.getPublic(), msg.getBytes(), sign);System.out.println("Verify result: " + isVerify);}
}

加密和解密(可选)
对于 SM2 来说,通常更多地用于数字签名而不是加密。但是,如果需要进行加密操作,可以参考如下方式:

// 注意:这里的加密/解密可能需要根据具体需求调整,因为SM2标准主要针对签名和密钥交换。
// 下面只是一个简化的例子,实际应用中应考虑更多的细节如密钥格式转换等。public static byte[] encrypt(PublicKey publicKey, byte[] data) throws Exception {// 这里简化了加密过程,真实场景中需要处理更多细节throw new UnsupportedOperationException("Encrypt operation for SM2 is not directly supported.");
}public static byte[] decrypt(PrivateKey privateKey, byte[] encryptedData) throws Exception {// 类似于加密,解密也需要特别处理throw new UnsupportedOperationException("Decrypt operation for SM2 is not directly supported.");
}
  1. 示例:SM3 哈希计算
import org.bouncycastle.crypto.digests.SM3Digest;public class SM3Example {public static byte[] hash(byte[] input) {SM3Digest digest = new SM3Digest();digest.update(input, 0, input.length);byte[] hash = new byte[digest.getDigestSize()];digest.doFinal(hash, 0);return hash;}public static void main(String[] args) {String msg = "Hello,国密!";byte[] hash = hash(msg.getBytes());System.out.println(Hex.toHexString(hash));}
}
  1. SM4 加解密示例
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.security.Security;public class SM4Example {static {Security.addProvider(new BouncyCastleProvider());}public static byte[] encrypt(byte[] key, byte[] data) throws Exception {Cipher cipher = Cipher.getInstance("SM4/ECB/PKCS5Padding");cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "SM4"));return cipher.doFinal(data);}public static byte[] decrypt(byte[] key, byte[] cipherText) throws Exception {Cipher cipher = Cipher.getInstance("SM4/ECB/PKCS5Padding");cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "SM4"));return cipher.doFinal(cipherText);}public static void main(String[] args) throws Exception {byte[] key = "1234567890abcdef".getBytes(); // 16 bytesbyte[] data = "Hello,SM4!".getBytes();byte[] encrypted = encrypt(key, data);System.out.println("Encrypted: " + Hex.toHexString(encrypted));byte[] decrypted = decrypt(key, encrypted);System.out.println("Decrypted: " + new String(decrypted));}
}

方式 2:使用国产 SDK(如:江南天安、三未信安、卫士通等厂商提供的 HSM 或 SDK)

如果你在银行、金融或政务系统中开发,可能需要使用硬件安全模块(HSM)来执行国密算法,这类设备通常提供 Java SDK 接口。


方式 3:自研封装(适合定制化需求)

对于有特殊合规要求的场景,可基于国密标准文档自行实现 SM2/SM3/SM4,但需注意以下几点:

  • 需要理解国密算法规范(GB/T 32918、GB/T 32905、GB/T 34957)
  • 自行实现容易出错,建议仅用于学习或已有完整测试用例时使用

✅ 三、辅助工具类:Hex 编码转换

public class Hex {private static final char[] HEX_CHARS = "0123456789abcdef".toCharArray();public static String toHexString(byte[] data) {StringBuilder sb = new StringBuilder(data.length * 2);for (byte b : data) {sb.append(HEX_CHARS[(b >> 4) & 0x0f]);sb.append(HEX_CHARS[b & 0x0f]);}return sb.toString();}
}

✅ 四、注意事项

  1. Bouncy Castle 的 Provider 名称问题

    • 在 Android 中使用时需要注意兼容性,某些方法名或类名可能不同。
    • 推荐使用 org.bouncycastle:crypto-extSpongyCastle(Android 适配版)。
  2. 算法模式

    • SM4 支持 ECB、CBC 等模式,加密时需选择合适的填充方式(如 PKCS5Padding)。
  3. 证书与签名验证(SM2)

    • SM2 不仅可用于加密,还可用于签名和验签,通常配合 X.509 证书使用。

✅ 五、参考文档

  • Bouncy Castle 官网
  • GB/T 32918-2016 SM2 公钥密码算法
  • GB/T 32905-2016 SM3 杂凑算法
  • GB/T 34957-2017 SM4 分组密码算法

http://www.xdnf.cn/news/13782.html

相关文章:

  • windows下tokenizers-cpp编译
  • FPGA基础 -- 什么是 Verilog 的模块(`module`)
  • 再现重大BUG,微软紧急撤回Win 11六月更新
  • Karate整合PlayWright方式之playWright Driver
  • Vulkan学习笔记4—图形管线基础
  • Visual Studio 里面的 Help Viewer 提示Error: “.cab未经Microsoft签名” 问题解决
  • 【Net】OPC UA(OPC Unified Architecture)协议
  • Fastadmin报错Unknown column ‘xxx.deletetime‘ in ‘where clause
  • [算法][好题分享][第三大的数][最短无序子数组]
  • 小飞电视:智能电视与移动设备的娱乐新选择
  • Meta发布V-JEPA 2世界模型及物理推理新基准,推动AI在物理世界中的认知与规划能力
  • Python 标准库之 os 模块
  • Vue + element实现电子围栏功能, 根据省市区选择围栏, 自定义围栏 ,手动输入地名围栏, 保存围栏,清除围栏,加载围栏,批量检测标点是否在围栏内。
  • Chapter05-SSRF
  • Nodejs特训专栏-基础篇:1. Node.js环境搭建与项目初始化详细指南
  • Conda 安装 nbextensions详细教程
  • C++编程语言:标准库:STL容器(Bjarne Stroustrup)
  • 2025【证券从业】时间事件
  • CHI 总线协议及一致性总线相关的 NOC
  • c/c++ 汇编码中的.cfi 指令有什么用途?
  • (LeetCode 每日一题) 3423. 循环数组中相邻元素的最大差值 (数组)
  • Java面试避坑指南:牛客网最新高频考点+答案详解
  • Mac电脑-Office 2024 长期支持版 PPT、Excel、Word(Mac中文)
  • RabbitMQ实现异步消息监听机制
  • Makefile 学习笔记
  • 无外接物理显示器的Ubuntu系统的远程桌面连接(升级版)
  • C#学习第30天: 匹配模式
  • 大模型技术30讲-5-利用数据来减少过拟合现象
  • Next.js + Supabase = 快速开发 = 高速公路
  • 怎样下载某个SCI期刊的endnote style?答:直接去endnote官网搜索期刊名称并下载即可