3. 国密算法库选择:BC与GMSSL对比,Maven依赖配置

做国密改造,第一个跳出来的实际问题就是:算法库用哪个?

说实话,选错库会让你后面多走不少弯路。我自己在早期项目里踩过这个坑,所以这一章我们踏踏实实把BC和GMSSL这两个主流方案掰扯清楚。

嗯,咱们先理清一个概念:BC是Bouncy Castle的简称,全球通用的加密库;GMSSL则是国密标准算法的专用开源实现。两者都能做国密,但定位差别挺大。

3.1 两个库的核心差异

我习惯从几个关键维度来判断一个库靠不靠谱。你想想看,生产环境不比搞实验,库的稳定性、社区活跃度、合规性都得过一遍。

对比维度 Bouncy Castle (BC) GMSSL
协议覆盖 全面(RSA、ECC、SM2/3/4) 专注国密(SM2/SM3/SM4)
合规认证 商用密码产品认证通过 密码行业标准遵循
社区活跃度 极高,持续维护 中等,更新节奏偏慢
Spring集成 原生支持、文档丰富 需额外适配
性能表现 成熟优化,适合通用场景 SM2签名/验签更快
我的经验:如果你的项目涉及国际算法与国密混合使用,选BC几乎没悬念。但如果目标是纯国密网关或硬件加密机对接,GMSSL的SM2签名性能确实更占优势。

3.2 为什么我更推荐BC?

说一个真实案例。有一次我接手一个Spring Cloud网关的改造项目,团队初选用了GMSSL。起初测试环境跑得挺顺,但一到线上就出了怪问题——RSA与SM2证书混用的TLS握手经常失败。

追查下来才发现,是GMSSL对JCE(Java Cryptography Extension)的默认Provider支持不够完整。当时我们得手动修改Bouncy Castle的Provider优先级,才能让RSA和SM2共存。说白了,GMSSL的API设计更“原生”,但和Spring Security的集成花了不少力气。

从那以后,我养成了一个习惯:非国密专有场景,优先上BC。它就像是瑞士军刀,什么都能干,而且Spring生态默认就认得它。

3.3 Maven依赖配置实战

直接上代码吧。我用的是Spring Boot 2.7.x + Spring Cloud 2021.0.x的版本组合,BC的Maven坐标如下:

<!-- Bouncy Castle 核心包 -->
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.70</version>
</dependency>

<!-- Bouncy Castle PKIX/CMS 扩展 -->
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcpkix-jdk15on</artifactId>
    <version>1.70</version>
</dependency>

<!-- 可选:TLS/DTLS 支持 -->
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bctls-jdk15on</artifactId>
    <version>1.70</version>
</dependency>
注意:版本号“1.70”是当前稳定版本。我在项目里见过有人用1.60以下的旧版,直接导致SM2曲线不支持的异常。升级BC后问题立刻解决。
另外,bcprov-jdk15on 是Provider核心,bcpkix 负责证书链处理。如果只做SM2/3/4签名验签,只引入bcprov即可。

如果是GMSSL的方案,配置是这样的:

<dependency>
    <groupId>com.gmssl</groupId>
    <artifactId>gmssl-xkcp</artifactId>
    <version>1.1.0</version>
</dependency>

<dependency>
    <groupId>com.gmssl</groupId>
    <artifactId>gmssl-jce</artifactId>
    <version>1.1.0</version>
</dependency>

你看,GMSSL的坐标明显少——它本身不做多余的事情。但问题在于,当你需要在Gateway里同时支持国际TLS和国密TLS时,GMSSL的JCE Provider注册会覆盖Bouncy Castle的一些服务。嗯,要处理这个就得调整Provider的优先级顺序。

3.4 选型总结与避坑

我的建议很直接:如果你的国密改造涉及Spring Cloud Gateway、Feign、Ribbon这些组件,直接用BC绕开麻烦。如果项目是纯国密内部调用,且硬件加密机只支持GMSSL协议,那选GMSSL更加轻量。

避坑指南:
  • 我曾遇到过BC和GMSSL同时出现在classpath中,导致SM2验签返回false。排查半天,发现是Provider冲突——Security.addProvider()的顺序问题。解决方案是显式指定优先用哪个Provider。
  • 还有一次,测试环境用JDK 8编译,生产环境是JDK 11。BC 1.70对JDK 11的签名算法有细微调整,不升级版本直接报错。所以版本对齐也很关键。
  • 另外,别把bcprov和bcprov-ext混用。我记得有一次问题就是因为同时引入了两个Provider类,导致运行时抛出DuplicateProvider异常。

3.5 知识结构一览

我把这一章的核心逻辑画成了图。你看,从你的项目需求出发,最终要落在稳定的Maven依赖上。

国密算法库选型决策路径 项目国密需求 Spring Cloud Gateway / Feign / 混合算法 纯国密内部系统 硬件加密机 / 单一协议 选用 Bouncy Castle 选用 GMSSL ⚠️ 注意Provider优先级与JDK版本兼容性

从图上可以看得很清楚:向左走是BC路线,适合Spring Cloud全家桶;向右走是GMSSL路线,适合单一国密环境。别站中间纠结,那是给自己找麻烦。