I use BouncyCastle for encryption in my application. When I run it standalone, everything works fine. However, if I put it in the webapp and deploy on JBoss server, I get a following error:
javax.servlet.ServletException: error constructing MAC: java.security.NoSuchProviderException: JCE cannot authenticate the provider BC
(...)
root cause
java.lang.Exception: error constructing MAC: java.security.NoSuchProviderException: JCE cannot authenticate the provider BC
(...)
root cause
java.io.IOException: error constructing MAC: java.security.NoSuchProviderException: JCE cannot authenticate the provider BC
org.bouncycastle.jce.provider.JDKPKCS12KeyStore.engineLoad(Unknown Source)
java.security.KeyStore.load(Unknown Source)
Here is a part of the code that causes this error:
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null)
{
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
}
// Read the Private Key
KeyStore ks = KeyStore.getInstance("PKCS12", BouncyCastleProvider.PROVIDER_NAME);
ks.load(new FileInputStream(certificatePath), privateKeyPassword.toCharArray());
And maven dependency:
<dependency>
<groupId>bouncycastle</groupId>
<artifactId>bcmail-jdk16</artifactId>
<version>140</version>
</dependency>
Do you know how could I deploy it?
For JBoss AS7 bouncy castle needs to be deployed as a server module. This replaces the server/default/lib
mechanism of earlier versions (as mentioned in Gergely Bacso's answer).
JBoss AS7 uses jdk1.6+. When using JBoss AS7 with jdk1.6 we need to make sure we are using bcprov-jdk16.
Create a Jboss module (a folder $JBOSS_HOME/modules/org/bouncycastle/main).
Put the bouncy castle jars that you want to be globally available in it, along with a module.xml
file that looks like this:
<module xmlns="urn:jboss:module:1.1" name="org.bouncycastle">
<resources>
<resource-root path="bcprov-jdk16-1.46.jar"/>
</resources>
<dependencies>
<module name="javax.api" slot="main" export="true"/>
</dependencies>
</module>
Once you have setup the module you need to make it available to your deployments. There are two ways:
In $JBOSS_HOME/standalone/configuration/standalone.xml replace
<subsystem xmlns="urn:jboss:domain:ee:1.0"/>
with
<subsystem xmlns="urn:jboss:domain:ee:1.0">
<global-modules>
<module name="org.bouncycastle" slot="main"/>
</global-modules>
</subsystem>
The jar libraries will now be available across all applications (and this will "emulate" adding to the classpath as was possible in jboss 4,5,6 etc)
Add a module dependency entry to the ear's META-INF/jboss-deployment-structure.xml
file, under the section, eg:
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.1">
<deployment>
<dependencies>
<module name="org.bouncycastle" slot="main" export="true" />
</dependencies>
</deployment>
</jboss-deployment-structure>