Bouncy Castle Providers

BouncyCastle 介绍

Bouncy Castle 是Java 加密拓展(JCE)的升级版本,相对Sun 提供的默认 JCE,它提供了许多密钥套件与算法。

除此之外,Bouncy Castle 有许多能读取像 PEM 和 ASN.1 这些晦涩格式的工具。这些格式正常人是不会想去自己重写一遍的。

在 Pulsar 中,安全与加密都对 BouncyCastle Jar 包有依赖。 关于Bouncy Castle FIPS的详细安装和配置,请参阅 BC FIPS 文档, 特别是 用户指南安全政策 PDF 文档。

Bouncy Castle 提供 FIPS 与 non-FIPS 两个版本。 但在 JVM 中,不能同时引入两个版本,所以需要先排除当前版本才能引入另一个版本。

在 Pulsar 中,安全和加密方法也依赖于 Bouncy Castle, 特别是 TLS 认证传输加密。 本文档包含使用 Pulsar 时的 Bounccastle FIPS(BC-FIPS)和 non-FIPS(BC-non-FIPS)版本的配置。

Pulsar 中打包 Bounccastle 模块

对于 Pulsar 中的bouncy-castle模块,我们提供了2个子模块:bouncy-castle-bc (针对 non-FIPS 版本)和bouncy-castle-bcfips(针对 FIPS 版本),将 BC jar 打包在一起,使 Bouncy Castle的包含和排除更容易。

为了实现这一目的,我们需要将几个 bouncy-castle jars 一起打包到 bouncy-castle-bcbouncy-castle-bfips 中。 因为每一个原始的 bouncy-castle jar 包都和安全有关,所以 BouncyCastle 为每个 JAR 包都提供了签名。 但是当我们重新打包时,Maven shade 机制引入了 BouncyCastle jar 文件,并将签名放入了 META-INF(这些签名对新的 uber-jar 无效,只适用于原始的 BC jar)。 通常,你会遇到这种报错:java.lang.SecurityException: Invalid signature file digest for Manifest main attributes

你可以在 mvn pom 文件中排除这些签名,以避免上面的错误:

  1. <exclude>META-INF/*.SF</exclude>
  2. <exclude>META-INF/*.DSA</exclude>
  3. <exclude>META-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

因此,我们需要使用 可执行软件包插件 。它通过 jar-in-jar 方法将 BouncyCastle 的签名在一个单独的、可执行的 jar 包中。

引入 BC-non-FIPS 的依赖

Pulsar 所用的bouncy-castle-bc模块,定义在bouncy-castle/bc/pom.xml文件内。它包含了 Pulsar 所需的 non-FIPS JAR包,该 JAR 包是使用 jar-in-jar 的方式打包的(即必须提供<classifier>pkg</classifier>)。

  1. <dependency>
  2. <groupId>org.bouncycastle</groupId>
  3. <artifactId>bcpkix-jdk15on</artifactId>
  4. <version>${bouncycastle.version}</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.bouncycastle</groupId>
  8. <artifactId>bcprov-ext-jdk15on</artifactId>
  9. <version>${bouncycastle.version}</version>
  10. </dependency>

通过使用 bouncy-castle-bc 模块,你可以轻松地将 Bouncycastle non-FIPS JAR 包引入或排除。

引入 BC-non-FIPS 模块(bouncy-castle-bc)

对于 Pulsar 客户端,用户需要使用 bouncy-castle 模块,所以pulsar-client-original将包含bouncy-castle-bc 模块。并且使用<classifier>pkg</classifier>设置和jar-in-jar包的引用关系。 引入依赖示例如下:

  1. <dependency>
  2. <groupId>org.apache.pulsar</groupId>
  3. <artifactId>bouncy-castle-bc</artifactId>
  4. <version>${pulsar.version}</version>
  5. <classifier>pkg</classifier>
  6. </dependency>

默认情况下,pulsar-client-original包含了bouncy-castle-bc模块。并且pulsar-client-original已经包含在许多其他模块中,例如pulsar-client-adminpulsar-broker
但是因为上面的 shade 包和签名的原因,我们将不会将bouncy-castle模块打包到pulsar-client-all的的其他 shade 模块目录中。例如pulsar-client-shaded, pulsar-client-admin-shadedpulsar-broker-shaded。 所以,在 shade 模块中,我们将排除 bouncy-castle模块。

  1. <filters>
  2. <filter>
  3. <artifact>org.apache.pulsar:pulsar-client-original</artifact>
  4. <includes>
  5. <include>**</include>
  6. </includes>
  7. <excludes>
  8. <exclude>org/bouncycastle/**</exclude>
  9. </excludes>
  10. </filter>
  11. </filters>

这意味着,bouncy-castle相关的 JAR 包不会被放在这些扩展的 Jar 包中。

BC-FIPS 模块 (bouncy-castle-bcfips)

bouncy-castle/bcfips/pom.xml 中定义的 Pulsar 模块 bouncy-castle-bcfips,包含了Pulsar 所需的 FIPS jar 包。 和 bouncy-castle-bc类似, bouncy-castle-bfips也是用 jar-in -jar 方式打包,以便引入/排除包.

  1. <dependency>
  2. <groupId>org.bouncycastle</groupId>
  3. <artifactId>bc-fips</artifactId>
  4. <version>${bouncycastlefips.version}</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.bouncycastle</groupId>
  8. <artifactId>bcpkix-fips</artifactId>
  9. <version>${bouncycastlefips.version}</version>
  10. </dependency>

排除 BC-non-FIPS 并引入 BC-FIPS

如果你想要从 BC-non-FIPS 切换到 BC-FIPS 版本,下面是 Pulsar-broker 模块的一个示例:

  1. <dependency>
  2. <groupId>org.apache.pulsar</groupId>
  3. <artifactId>pulsar-broker</artifactId>
  4. <version>${pulsar.version}</version>
  5. <exclusions>
  6. <exclusion>
  7. <groupId>org.apache.pulsar</groupId>
  8. <artifactId>bouncy-castle-bc</artifactId>
  9. </exclusion>
  10. </exclusions>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.apache.pulsar</groupId>
  14. <artifactId>bouncy-castle-bcfips</artifactId>
  15. <version>${pulsar.version}</version>
  16. <classifier>pkg</classifier>
  17. </dependency>

更多的示例, 您可以参考 bcfips-include-test模块。