blob: fd645111ad8c47aa83c12b4f6af47589c14d3edf [file] [view]
---
id: security-bouncy-castle
title: Bouncy Castle Providers
sidebar_label: "Bouncy Castle Providers"
description: Get a comprehensive understanding of concepts and packaging methods of BouncyCastle in Pulsar.
---
## BouncyCastle Introduce
`Bouncy Castle` is a Java library that complements the default Java Cryptographic Extension (JCE),
and it provides more cipher suites and algorithms than the default JCE provided by Sun.
In addition to that, `Bouncy Castle` has lots of utilities for reading arcane formats like PEM and ASN.1 that no sane person would want to rewrite themselves.
In Pulsar, security and crypto have dependencies on BouncyCastle Jars. For the detailed installing and configuring Bouncy Castle FIPS, see [BC FIPS Documentation](https://www.bouncycastle.org/documentation.html), especially the **User Guides** and **Security Policy** PDFs.
`Bouncy Castle` provides both [FIPS](https://www.bouncycastle.org/fips_faq.html) and non-FIPS versions. But in a JVM, you can not include both of the 2 versions, and you need to exclude the current version before including the other.
In Pulsar, the security and crypto methods also depend on `Bouncy Castle`, especially in [mTLS authentication](security-tls-authentication.md) and [Transport Encryption](security-encryption.md). This document contains the configuration between BouncyCastle FIPS(BC-FIPS) and non-FIPS(BC-non-FIPS) version while using Pulsar.
## How BouncyCastle modules packaged in Pulsar
In Pulsar's `bouncy-castle` module, We provide 2 sub modules: `bouncy-castle-bc`(for non-FIPS versions) and `bouncy-castle-bcfips`(for FIPS version), to package BC jars together to make the include and exclude of `Bouncy Castle` easier.
To achieve this goal, we will need to package several `bouncy-castle` jars together into `bouncy-castle-bc` or `bouncy-castle-bcfips` jar.
Each of the original bouncy-castle jars is related to security, so BouncyCastle dutifully supplies signed of each jar.
But when we do the re-package, Maven shade explodes the BouncyCastle jar file which puts the signatures into META-INF,
these signatures aren't valid for this new, uber-jar (signatures are only for the original BC jar).
Usually, You will meet error like `java.lang.SecurityException: Invalid signature file digest for Manifest main attributes`.
You can exclude these signatures in the mvn pom file to avoid the above error.
```xml
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
```
But it can also lead to new, cryptic errors, e.g. `java.security.NoSuchAlgorithmException: PBEWithSHA256And256BitAES-CBC-BC SecretKeyFactory not available`
By explicitly specifying where to find the algorithm like this: `SecretKeyFactory.getInstance("PBEWithSHA256And256BitAES-CBC-BC","BC")`
It will get the real error: `java.security.NoSuchProviderException: JCE cannot authenticate the provider BC`
So, we used a [executable packer plugin](https://github.com/nthuemmel/executable-packer-maven-plugin) that uses a jar-in-jar approach to preserve the BouncyCastle signature in a single, executable jar.
### Include dependencies of BC-non-FIPS
Pulsar module `bouncy-castle-bc`, which is defined by `bouncy-castle/bc/pom.xml` contains the needed non-FIPS jars for Pulsar, and packaged as a jar-in-jar(need to provide `<classifier>pkg</classifier>`).
```xml
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>${bouncycastle.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-ext-jdk15on</artifactId>
<version>${bouncycastle.version}</version>
</dependency>
```
By using this `bouncy-castle-bc` module, you can easily include and exclude BouncyCastle non-FIPS jars.
### Modules that include BC-non-FIPS module (`bouncy-castle-bc`)
For Pulsar client, user need the bouncy-castle module, so `pulsar-client-original` will include the `bouncy-castle-bc` module, and have `<classifier>pkg</classifier>` set to reference the `jar-in-jar` package.
It is included as the following example:
```xml
<dependency>
<groupId>org.apache.pulsar</groupId>
<artifactId>bouncy-castle-bc</artifactId>
<version>${pulsar.version}</version>
<classifier>pkg</classifier>
</dependency>
```
By default `bouncy-castle-bc` already included in `pulsar-client-original`, And `pulsar-client-original` has been included in a lot of other modules like `pulsar-client-admin`, `pulsar-broker`.
But for the above shaded jar and signatures reason, we should not package Pulsar's `bouncy-castle` module into `pulsar-client-all` other shaded modules directly, such as `pulsar-client-shaded`, `pulsar-client-admin-shaded` and `pulsar-broker-shaded`.
So in the shaded modules, we will exclude the `bouncy-castle` modules.
```xml
<filters>
<filter>
<artifact>org.apache.pulsar:pulsar-client-original</artifact>
<includes>
<include>**</include>
</includes>
<excludes>
<exclude>org/bouncycastle/**</exclude>
</excludes>
</filter>
</filters>
```
That means, `bouncy-castle` related jars are not shaded in these fat jars.
### Module BC-FIPS (`bouncy-castle-bcfips`)
Pulsar module `bouncy-castle-bcfips`, which is defined by `bouncy-castle/bcfips/pom.xml`, contains the needed FIPS jars for Pulsar.
Similar to `bouncy-castle-bc`, `bouncy-castle-bcfips` is also packaged as a `jar-in-jar` package for easy include/exclude.
```xml
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bc-fips</artifactId>
<version>${bouncycastle.bc-fips.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-fips</artifactId>
<version>${bouncycastle.bcpkix-fips.version}</version>
</dependency>
```
### Exclude BC-non-FIPS and include BC-FIPS
If you want to switch from BC-non-FIPS to BC-FIPS version, Here is an example for `pulsar-broker` module:
```xml
<dependency>
<groupId>org.apache.pulsar</groupId>
<artifactId>pulsar-broker</artifactId>
<version>${pulsar.version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.pulsar</groupId>
<artifactId>bouncy-castle-bc</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.pulsar</groupId>
<artifactId>bouncy-castle-bcfips</artifactId>
<version>${pulsar.version}</version>
<classifier>pkg</classifier>
</dependency>
```
For more example, you can reference module `bcfips-include-test`.