10

Background

I am trying to use bouncy castle library to decrypt private keys in my war. Now I tested the code first in a standalone app and it worked fine. Now when I am testing it as a webapp in Wildfly8.0 am facing some issues with Bouncy castle.

The Wildfly 8.0 am using has bouncy castle provider module installed. The BC version being used in v1.46.

The code that I have developed uses v1.51. I have followed the steps mentioned here:

Already tried

  • Installing the JCE policy files.
  • Adding to the provider list.

Problem

The error I am getting is :

unable to read encrypted data: JCE cannot authenticate the provider BC 

And the code which triggers the above error, in as follows :

PKCS8EncryptedPrivateKeyInfo kp = (PKCS8EncryptedPrivateKeyInfo) keyPair;  
InputDecryptorProvider pkcs8dec = new JceOpenSSLPKCS8DecryptorProviderBuilder()  
      .setProvider(new BouncyCastleProvider())  
      .build("somepass".toCharArray());  
PrivateKeyInfo pko = kp.decryptPrivateKeyInfo(pkcs8dec);<-- ##Error here  

Also to add the details,in my pom.xml I have added the jar with compile scope, so the libs are copied into the war and get installed in WEB-INF/lib.

Any tips to fix the above problem?

Community
  • 1
  • 1
eminemence
  • 721
  • 1
  • 6
  • 21
  • The 'JBoss AS7: ...' question you reference says to "Create a Jboss module (a folder [...]). Put the bouncy castle jars that you want to be globally available in it, along with a module.xml file [...]", but above you say the BC jar gets installed in WEB-INF/lib. Is it possible you have misunderstood the instructions there? – Peter Dettman Apr 21 '15 at 05:26
  • There is an existing JBoss module with BC v1.46. I want to use BC v1.51 with my webapp. I cannot upgrade the JBoss module to use BC v1.51 as there are other webapps are dependent on the v1.46. Hope this makes it clear. – eminemence Apr 21 '15 at 05:33
  • 1
    Can't you create a second module for 1.51? – Peter Dettman Apr 21 '15 at 05:37
  • I just want to keep it as isolated as possible and keeping it at war level seems to be best possible solution. – eminemence Apr 21 '15 at 10:29
  • I know I had issues using JCE providers that weren't loaded by the root class loader. In your case, are you sure the BouncyCastleProvider instance you instantiate comes from the proper class loader and has the proper version? I suppose a wild idea would be to modify your version of BouncyCastle to use a different name than BC and put it alongside the existing version, so you wouldn't impact the other apps. – JP Moresmau Apr 21 '15 at 16:27
  • When you say that other modules use BC v1.46, Do you mean that the bcprov*-146.jar is in the `$JAVA_HOME/jre/lib/ext` folder? – JuanKB1024 Apr 23 '15 at 22:11
  • Is there anyway to extend the bounty?I need time to evaluate the solution provided and that may take one more day. – eminemence Apr 27 '15 at 06:33
  • You can't have 2 version of BC in the same VM. JCE is loaded in the root class loader and have a reference on the provider mapped on the name. You will need to have your own JCE provider base on BC. – Kazaag Apr 27 '15 at 11:19
  • Hi @Kazaag, Can you please elaborate? Are you saying the same thing as _xerx593_. If not, then can you add more details. – eminemence Apr 28 '15 at 09:58
  • 1
    The JCE api have static reference to the map of registered providers. The JCE class are from the parent class loader. If 2 implementation coming form different class loader try to register them self on the same name, overwriting each other. So one of the user code will received the wrong one (and probably from a class loader it doesn't have access) – Kazaag Apr 30 '15 at 09:29

1 Answers1

3

I. Combining the idea of Peter (@comment) and https://developer.jboss.org/thread/175395, create "your own bc version" with a custom name:

  1. Create an 'my.bouncycastle' module in the following manner:

    • Under $JBOSS_HOME/modules, create directory 'my/bouncycastle/main'. Directory 'my' might not be there. ;)

    • Copy bcprov-[your-version].jar into my/bouncycastle/main

    • Create file 'bcprov-[your-version].jar.index' in my/bouncycastle/main, which is basically the output of a jar -tf command without the ".class" lines. (pipe&edit...)

      I put a blank line at the top because these .index files always seem to have one. I have attached this file as "bcprov-jdk16-1.46.jar.index".

    • Create a file called "module.xml", also in my/bouncycastle/main, which will point to the jar file and reference module "javax.api" as a dependency.

      I have attached this file as 'module.xml'. The module is complete.

  1. Since I am deploying in an EAR file, I had to add a module dependency entry to my EAR's META-INF/jboss-deployment-structure.xml file, under the section, like so:

(the statement also applies to WAR files, when deployed on top-level, use the custom name as module reference)

    <deployment><dependencies><module name="my.bouncycastle" slot="main" export="true"/>  
  1. Make certain that the ear's /lib directory does NOT contain bcprov-[your-version].jar. (actually II.)

Notes: The 'slot="main" and 'export="true" parameters are very important in the jboss-dependency-structure.xml file...

II. Adjust your maven dependency(ies) to:

<scope>provided</scope>

Note: Don't change the maven dependecy(ies group artifacts) to "my.bouncycastle", only the scope, this will ensure you a nice compile-time-behavior by the most IDE's AND will prevent your (maven-)war/jar/ear-plugin from packaging it into libs! (And which would be anyway the correct scope for a dependency like this.)

xerx593
  • 12,237
  • 5
  • 33
  • 64