首页/新闻资讯/正文详情

Apache Pulsar 中 Bouncy Castle 安全提供者的打包机制与 FIPS 切换实战指南

发布时间:2026/9/23 13:28:16 来源:云帆数科 栏目:资讯中心
Apache Pulsar 中 Bouncy Castle 安全提供者的打包机制与 FIPS 切换实战指南
Apache Pulsar 中 Bouncy Castle 安全提供者的打包机制与 FIPS 切换实战指南【免费下载链接】pulsarApache Pulsar - distributed pub-sub messaging system项目地址: https://gitcode.com/gh_mirrors/pulsar28/pulsar导读Apache Pulsar 的 TLS 认证、传输加密等安全与加密能力底层依赖Bouncy CastleBC这个 Java 加密库。为了让用户能够在一套构建体系下轻松地在 BC 非 FIPS 版本与 FIPS 版本之间切换Pulsar 在bouncy-castle模块中设计了jar-in-jar的打包方案并配套提供了BouncyCastleLoader/BouncyCastleFipsLoader两个 Provider 加载器。本文将基于 Pulsar 仓库中的实际文档与源码讲清 BC 在 Pulsar 中如何被打包、如何被引入、为什么 shadedfat jar模块必须排除 BC以及如何把 Broker 从 BC-non-FIPS 平滑切换到 BC-FIPS。Bouncy Castle 与 Pulsar 的关系Bouncy Castle是一个补充 Java 默认 JCEJava Cryptographic Extension的 Java 加密库。相对于 Sun/Oracle JVM 自带的 JCE它提供了更多密码套件cipher suites与算法同时还内置了大量解析 PEM、ASN.1 等晦涩格式的工具类——这些格式通常没有开发者愿意自己重新实现。在 Pulsar 中安全与加密切面普遍依赖 Bouncy Castle 的 Jar 包典型场景包括TLS 认证TLS Authentication详见 site2/docs/security-tls-authentication.md该文档明确指出Bouncy Castle Provider 为 Pulsar 提供 TLS 相关的密码套件与算法如果需要 FIPS 版本请参考 Bouncy Castle 页面。传输加密Transport Encryption / 端到端消息加密详见 site2/docs/security-encryption.md。由于安全与加密是 Pulsar 的刚性依赖BC 的 Jar 会以多种方式出现在 Broker、Client 及其 shaded 产物中这直接导致了本文要讨论的打包与版本切换问题。FIPS 与非 FIPS二者不可共存Bouncy Castle官方同时提供FIPS 版本与非 FIPS 版本本文简称 BC-FIPS 与 BC-non-FIPS。二者在 JVM 中不能同时存在在一个 JVM 里引入其中一个版本时必须先排除另一个版本否则 Provider 注册会出现冲突。关于 BC-FIPS 的详细安装与配置如 FIPS 模式下的 self-test、Policy 文件等Bouncy Castle 官方文档提供了专门的User Guides与Security Policy两份 PDF需要部署 FIPS 环境时务必参考官方材料。本仓库侧重点是 Pulsar 如何在构建层面支持两种版本的切换。从 Pulsar 源码可以看到两套 Provider 在运行时拥有独立的注册名称非 FIPS 版本注册名为BC对应类org.bouncycastle.jce.provider.BouncyCastleProviderFIPS 版本注册名为BCFIPS对应类org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider。这两个常量定义在 pulsar-common/src/main/java/org/apache/pulsar/common/util/SecurityUtility.java 中public static final String BC_FIPS_PROVIDER_CLASS org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider; public static final String BC_NON_FIPS_PROVIDER_CLASS org.bouncycastle.jce.provider.BouncyCastleProvider; public static final String BC_FIPS BCFIPS; public static final String BC BC;运行时SecurityUtility.getProvider()会先检查BC与BCFIPS是否已注册再决定返回哪个 Provider从 classpath 加载时则优先尝试非 FIPS 版本失败后再尝试 FIPS 版本这是出于向后兼容性的考虑见 SecurityUtility.java。isBCFIPS()方法则通过比对 Provider 的类名来判断当前是否处于 FIPS 模式。Pulsar 的 bouncy-castle 模块两个子模块 一个测试模块Pulsar 在 bouncy-castle/pom.xml 中定义了一个名为bouncy-castle-parent的父模块其注释点明了设计目标make it easy for user to load Bouncy Castle and Bouncy Castle FIPS即让用户能方便地引入/排除 BC 与 BC-FIPS。它聚合了三个子模块子模块ArtifactId用途bcbouncy-castle-bc打包 Pulsar 需要的 BC 非 FIPS Jar供 NAR/常规依赖使用bcfipsbouncy-castle-bcfips打包 Pulsar 需要的 BC FIPS Jar供 NAR/常规依赖使用bcfips-include-testbcfips-include-test用于验证 Broker Client 在引入 FIPS 版本后认证功能正常的测试模块jar-in-jar为什么不能直接打一个 uber-jar打包思路是把多个 Bouncy Castle Jar 合并进一个bouncy-castle-bc/bouncy-castle-bcfipsJar 中以简化引入与排除。但这里有一个关键障碍签名。每个原始 Bouncy Castle Jar 都与安全相关BC 官方对每个 JAR 都进行了签名。使用常规 Maven Shade 插件做 re-package 时Shade 会把 BC Jar解包explode并把签名文件放入META-INF。由于签名只对原始 BC Jar 有效重新合并出的 uber-jar 里这些签名就是非法的。此时运行会报出经典错误java.lang.SecurityException: Invalid signature file digest for Manifest main attributes常规解法是在 pom 中把这些签名文件排除掉excludeMETA-INF/*.SF/exclude excludeMETA-INF/*.DSA/exclude excludeMETA-INF/*.RSA/exclude但排除签名会引发另一类更难排查的错误例如java.security.NoSuchAlgorithmException: PBEWithSHA256And256BitAES-CBC-BC SecretKeyFactory not available当显式指定算法来源后SecretKeyFactory.getInstance(PBEWithSHA256And256BitAES-CBC-BC, BC)会暴露真正的根因java.security.NoSuchProviderException: JCE cannot authenticate the provider BC这正是 JCE 无法认证 Provider 的典型表现——Provider 的 Jar 签名不合法。为此Pulsar 采用了executable-packer-maven-pluginde.ntcomputer:executable-packer-maven-plugin的jar-in-jar方案外层是一个可执行 jar内部嵌套存放原始的、保持完整签名的 Bouncy Castle Jar从而既保留 BC 的签名有效性又得到单一可用的 Jar 产物。两个模块的 pom 中都以mainClass指定了对应的 Loader 类bouncy-castle/bc/pom.xmlmainClass为org.apache.pulsar.bcloader.BouncyCastleLoaderbouncy-castle/bcfips/pom.xmlmainClass为org.apache.pulsar.bcloader.BouncyCastleFipsLoader。使用 jar-in-jar 产物时需要在依赖声明中显式带上classifierpkg/classifier。Loader 类的职责jar-in-jar 的入口即 pom 中指定的 mainClass是 Pulsar 自定义的 Provider 加载器二者均实现org.apache.pulsar.common.util.BCLoader接口见 pulsar-common/src/main/java/org/apache/pulsar/common/util/BCLoader.javapublic interface BCLoader { Provider getProvider(); }BouncyCastleLoader.java非 FIPS静态初始化块中检查Security.getProvider(BC)是否为空为空则Security.addProvider(new BouncyCastleProvider())并记录 Provider 信息BouncyCastleFipsLoader.javaFIPS逻辑相同但注册的是BouncyCastleFipsProvider名称是BCFIPS。运行时 Pulsar 的SecurityUtility会根据 classpath 上实际存在的 Provider 类自动选择加载哪一套这也是两种版本二选一在代码层面的落点。引入 BC-non-FIPSbouncy-castle-bc 模块bouncy-castle-bc由 bouncy-castle/bc/pom.xml 定义打包了 Pulsar 所需的非 FIPS Jar以 jar-in-jar 形式发布需要classifierpkg/classifier。其依赖如下dependency groupIdorg.bouncycastle/groupId artifactIdbcpkix-jdk15on/artifactId version${bouncycastle.version}/version /dependency dependency groupIdorg.bouncycastle/groupId artifactIdbcprov-ext-jdk15on/artifactId version${bouncycastle.version}/version /dependency当前仓库根 pom.xml 中定义的版本为bouncycastle.version1.69/bouncycastle.version bouncycastlefips.version1.0.2/bouncycastlefips.version其中bcprov-ext-jdk15on提供带扩展算法实现的加密 Providerbcpkix-jdk15on提供 PKIX、CMS、TSP 等更高层的证书与消息处理 API。通过bouncy-castle-bc这一个模块用户即可完成对 BC 非 FIPS Jar 集合的整体引入或整体排除。哪些模块默认带上了 bouncy-castle-bcPulsar Client 侧需要使用 Bouncy Castle因此pulsar-client-originalpulsar-client模块会引入bouncy-castle-bc并设置classifierpkg/classifier指向 jar-in-jar 产物见 pulsar-client/pom.xmldependency groupIdorg.apache.pulsar/groupId artifactIdbouncy-castle-bc/artifactId version${project.parent.version}/version classifierpkg/classifier /dependency而pulsar-client-original又被大量其他模块依赖例如pulsar-client-admin、pulsar-brokerpulsar-broker/pom.xml 依赖pulsar-client-original因此默认情况下 BC 非 FIPS Jar 会随着这些模块一起进入 classpath。shaded 模块为何必须排除 BC由于上文所述的 jar 签名原因Pulsar不会把bouncy-castle相关模块直接打进pulsar-client-all及其他的 shaded 产物例如pulsar-client-shaded、pulsar-client-admin-shaded、pulsar-broker-shaded。在这些 shaded 模块的 maven-shade-plugin 配置中会对pulsar-client-original做如下过滤filters filter artifactorg.apache.pulsar:pulsar-client-original/artifact includes include**/include /includes excludes excludeorg/bouncycastle/**/exclude /excludes /filter /filters仓库中 pulsar-broker-shaded/pom.xml、pulsar-client-shaded/pom.xml、pulsar-client-admin-shaded/pom.xml 均有同样的排除配置并配有注释 bouncycastle jars could not be shaded, or the signatures will be wrong。这意味着这些 fat jar 中不会包含 bouncy-castle 相关 Jar。使用 shaded 产物的用户需要按自己的安全策略自行引入 BC通常显式声明bouncy-castle-bc或bouncy-castle-bcfips依赖从而避免因 shade 解包导致的签名失效问题。引入 BC-FIPSbouncy-castle-bcfips 模块bouncy-castle-bcfips由 bouncy-castle/bcfips/pom.xml 定义打包了 Pulsar 所需的 FIPS Jar。与bouncy-castle-bc类似它同样以 jar-in-jar 形式发布便于整体引入与排除依赖如下dependency groupIdorg.bouncycastle/groupId artifactIdbc-fips/artifactId version${bouncycastlefips.version}/version /dependency dependency groupIdorg.bouncycastle/groupId artifactIdbcpkix-fips/artifactId version${bouncycastlefips.version}/version /dependency即 FIPS 版本对应替换为bc-fips与bcpkix-fips版本由${bouncycastlefips.version}统一管理当前仓库为1.0.2。实战从 BC-non-FIPS 切换到 BC-FIPS切换的本质是先排除非 FIPS 的bouncy-castle-bc再引入 FIPS 的bouncy-castle-bcfipspkgclassifier。以pulsar-broker模块为例dependency groupIdorg.apache.pulsar/groupId artifactIdpulsar-broker/artifactId version${pulsar.version}/version exclusions exclusion groupIdorg.apache.pulsar/groupId artifactIdbouncy-castle-bc/artifactId /exclusion /exclusions /dependency dependency groupIdorg.apache.pulsar/groupId artifactIdbouncy-castle-bcfips/artifactId version${pulsar.version}/version classifierpkg/classifier /dependency同样的思路也适用于 Client 侧pulsar-client-original、pulsar-client-admin等依赖了bouncy-castle-bc的模块先排除再引入 FIPS 版本。参考实现bcfips-include-test 模块仓库中 bouncy-castle/bcfips-include-test/pom.xml 是官方提供的最完整切换示例它在依赖pulsar-broker的两处声明test-jar 与普通 test 依赖中都排除了bouncy-castle-bc然后单独引入bouncy-castle-bcfipsdependency groupIdorg.apache.pulsar/groupId artifactIdbouncy-castle-bcfips/artifactId version${project.version}/version classifierpkg/classifier /dependency其注释明确写道exclude bouncy castle, then load fips version。配套的测试代码 bouncy-castle/bcfips-include-test/src/test/java/org/apache/pulsar/client/TlsProducerConsumerTest.java 在 FIPS 环境下验证了三类 TLS 场景大消息传输验证超过单个 TLS chunk 上限2^14字节的16KB1字节消息可以正常生产/消费二进制协议双向 TLS 认证不带客户端证书时握手应失败携带证书后消费可成功HTTP 协议双向 TLS 认证同样验证无证书失败、有证书成功。这套用例证明了切换后的 FIPS 环境在真实 Broker/Client 交互中可用。可以按需在本地运行该模块的测试来验证自己的切换配置mvn test -pl bouncy-castle/bcfips-include-test切换后运行时的注意事项FIPS 模式下 Provider 名称是BCFIPS。若代码中硬编码了SecretKeyFactory.getInstance(..., BC)这类写法需要确认 Pulsar 的SecurityUtility已统一通过 Provider 常量获取实例从 SecurityUtility.java 的注释可见BC/BCFIPS常量同时用于Security.getProvider以及CertificateFactory.getInstance(X.509, BCFIPS)之类的工厂调用。一个 JVM 内不得同时出现bouncy-castle-bc与bouncy-castle-bcfips切换时必须借助exclusions彻底排除旧版本避免Security.addProvider阶段出现 Provider 冲突或算法查找异常。FIPS 本身对算法与密钥强度有严格约束涉及 Policy、Self-test 等这些属于 BC 官方 Security Policy 文档的范畴在搭建 FIPS 合规环境前应完整阅读官方材料。常见错误速查现象根因处理方式java.lang.SecurityException: Invalid signature file digest for Manifest main attributesShade 解包导致 BC 签名失效不要对 BC 做 shade改用bouncy-castle-bc/bouncy-castle-bcfips的 jar-in-jarpkgclassifier产物java.security.NoSuchAlgorithmException: PBEWithSHA256And256BitAES-CBC-BC SecretKeyFactory not availableProvider 未正确注册或签名被破坏确认引入的是完整签名产物并检查是否同时混入了两套 BCjava.security.NoSuchProviderException: JCE cannot authenticate the provider BCProvider 认证失败签名不合法在 shaded 模块中排除org/bouncycastle/**单独引入官方打包模块FIPS 切换后算法不可用JVM 中同时存在两套 BC或仍在使用BC硬编码使用exclusions排除bouncy-castle-bc统一走SecurityUtility的 Provider 常量总结Pulsar 通过bouncy-castle父模块下的bouncy-castle-bc与bouncy-castle-bcfips两个 jar-in-jar 产物将 Bouncy Castle 的引入与排除收敛为两个清晰的坐标从根本上规避了 Shade 解包破坏 Jar 签名导致的 Provider 认证问题BouncyCastleLoader/BouncyCastleFipsLoader与SecurityUtility则在运行时完成 Provider 的选择与注册。无论是默认的非 FIPS 部署还是合规要求下的 FIPS 部署只需遵循排除 bouncy-castle-bc → 引入 bouncy-castle-bcfipspkg classifier这一条主线即可完成安全底座的整体切换并借助bcfips-include-test模块完成端到端验证。【免费下载链接】pulsarApache Pulsar - distributed pub-sub messaging system项目地址: https://gitcode.com/gh_mirrors/pulsar28/pulsar创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

SSET 通信协议模块选型指南:从 CE-AJ12N 的 RS485 底座,讲到 Modbus-TCP / Profibus DP / Profinet 的落地路径
SSET 通信协议模块选型指南:从 CE-AJ12N 的 RS485 底座,讲到 Modbus-TCP / Profibus DP / Profinet 的落地路径

圣斯尔 SSET 非接触电流电压传感器(主推型号 CE-AJ12N)的原生输出只有一种:RS485 Modbus。0-800A 量程内电流精度 ≤0.5%、电压精度 ≤1.5%、功率精度 ≤1.0%,45-65Hz,15VDC 辅助电源,3KV 脉冲群抗扰度&am… · 2026/9/23 13:28:02

3个步骤搞定瞳距怎么测量,从入门到精通的避坑指南
3个步骤搞定瞳距怎么测量,从入门到精通的避坑指南

3个步骤搞定瞳距怎么测量,从入门到精通的避坑指南 版本升级后 API 全变了,这种崩溃感只有写过代码的人懂。今天聊瞳距怎么测量,别以为这只是验光单上的一个数字,它背后涉及计算机视觉、几何投影甚至光学物理的底层逻辑。很多前端和算法工程师在接入… · 2026/9/23 13:28:02

open-code-review:基于Git Diff与LLM Agent的结构化代码审查协议
open-code-review:基于Git Diff与LLM Agent的结构化代码审查协议

1. 项目概述:这不是一个“代码审查工具”,而是一套可嵌入开发流程的开源协作协议open-code-review 这个名字乍看像某个 GitHub Action 或 VS Code 插件,但实际它根本不是传统意义上的“工具”。我第一次在 Hugging Face 的一个冷门仓库里看到… · 2026/9/23 13:28:02

3步搞定熊猫烧香专杀:图解原理让复制代码跑通
3步搞定熊猫烧香专杀:图解原理让复制代码跑通

3步搞定熊猫烧香专杀:图解原理让复制代码跑通 复制来的代码跑不通不知道怎么调? 别急着删库跑路,这大概率不是你的问题,而是你没看懂底层的 图解原理… · 2026/9/23 15:33:29

【保姆级入门】CTF 比赛全解析:赛事介绍、核心考点、必备技术储备
【保姆级入门】CTF 比赛全解析:赛事介绍、核心考点、必备技术储备

在网络安全领域,CTF(Capture The Flag,夺旗赛)是检验技术实力的 “试金石”,也是白帽黑客成长的 “练兵场”。对于刚接触网络安全的新手来说,CTF 既神秘又充满吸引力 —— 它不像传统考试那样侧重理论&… · 2026/9/23 15:33:29

面试必问极限祭坛奖励机制源码拆解,3行代码搞定奖励逻辑
面试必问极限祭坛奖励机制源码拆解,3行代码搞定奖励逻辑

面试必问极限祭坛奖励机制源码拆解,3行代码搞定奖励逻辑 昨晚加班到凌晨两点,对着屏幕上的报错日志发呆。 NullPointerException 像幽灵一样在堆栈里跳来跳去,StackTrace… · 2026/9/23 15:33:23

agent科研相关前沿进展与应用方向探索
agent科研相关前沿进展与应用方向探索

刚接触一个新领域,最怕的就是迷失在海量的外国文献里,读了很多篇还是理不清脉络。我曾经也以为“研究现状”只能靠逐篇阅读、手动总结,直到发现了一些能生成“知识图谱”的神器。它们能让你像开了上帝视角一样,瞬间看清一个领域的… · 2026/9/23 15:33:23

Windows 下 Claude Code 接入 Playwright-MCP 调用本机 Edge 浏览器:配置文件与避坑验证
Windows 下 Claude Code 接入 Playwright-MCP 调用本机 Edge 浏览器:配置文件与避坑验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/23 15:33:17

【网安】必备知识
【网安】必备知识

长期更新补充,建议关注收藏点赞! 目录学习路线tips总结报文加密专栏一、基于加密算法的报文加密二、混合加密(对称加密 非对称加密)三、报文完整性与认证(非加密但相关)四、传输层安全协议(如 … · 2026/9/23 15:33:17

3招搞定手机怎么下载微信面试难题实战项目解析
3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧
Win7无线热点配置工具源码解析:解决API失效的3个实战技巧

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧 Win7无线热点配置工具在Win10/11上跑不动?不是你的问题,是版本升级后 API 全变了。很多老项目里的 netsh wlan… · 2026/9/23 0:00:36

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码