'Packaging Java application with BouncyCastle in a single JAR
Is it possible to package a Java app using BouncyCastle as security provider in a single JAR ?
PS: I expect to run the JAR without changing java security properties (in other words, without adding BouncyCastle as Security provider in JRE)
Solution 1:[1]
Please ensure you have some reasonable expectations and understanding regarding on how BouncyCastle and other security providers work.
For the latest BouncyCastle package and version information please review: https://www.bouncycastle.org/latest_releases.html
You don't have to download the JAR files from the above link. For the appropriate signed Maven packages see: https://mvnrepository.com/artifact/org.bouncycastle
The solution to this problem is to use https://github.com/nthuemmel/executable-packer-maven-plugin as suggested in the comments. Using the shade plugin (or many others) results in the BC JARs being repacked, breaking the security of the packages - causing failures when you attempt to run your uber JAR.
You still need to set the provider as BouncyCastle regardless.
The pom.xml
file should have BouncyCastle listed as a dependency:
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk18on</artifactId>
<version>1.71</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk18on</artifactId>
<version>1.71</version>
</dependency>
(Which specific packages you need may vary.)
In your pom.xml
you should also have something like the following in the plugins section:
<plugin>
<groupId>de.ntcomputer</groupId>
<artifactId>executable-packer-maven-plugin</artifactId>
<version>1.0.1</version>
<configuration>
<mainClass>com.ericsson.ml66.pki.Pki</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>pack-executable-jar</goal>
</goals>
</execution>
</executions>
</plugin>
In your code, within your class initialisation or other pertinent location, you should have:
if (Security.getProvider("BC") == null) {
Security.addProvider(new BouncyCastleProvider());
}
For good measure and to ensure the correct provider is used, I would also do specify the BouncyCastle provided where needed, such as:
PEMEncryptor encryptor =
new JcePEMEncryptorBuilder("AES-256-CBC").setProvider("BC").build(passphrase);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Raphael Krausz |