Search code examples
javajarbouncycastle

BouncyCastle SecurityException throws only when the *bcprov*.jar is packaged into the generated JAR


I have a strange problem. I wrote a Java application to do some cryptography things (encrypt with AES and digital signature with ECDSA). I decided to use the BouncyCastle API...I tried my application in Eclipse and everything went good. Then, I exported the application into a 'Runnable JAR File' with Eclipse Wizard, and I choosed the option 'Package required libraries into generated JAR'. Then I launch the JAR and the application throws the unluckily famous exception

java.security.NoSuchProviderException: JCE cannot authenticate the provider BC

So, I read something here and on other sites. Someone wrote that it necessary to modify the java.security file and add the BouncyCastleProvider. I also add the JAR of BouncyCastle into jre/lib/ext/, but the exception still throwing. Then I found that someone wrote that I need to change the library exporting order in my JAR. So, inspired by this, I re-exported the JAR with the option 'copy required libraries into a sub-folder next to the generated JAR'. I run the new JAR and everything went good. At the end of this big introduction (thanks for your patience) my question is: why now the SecurityException doesn't been thrwon? Why does put libraries out of the JAR work? EDIT: I have fixed the problem and I understand why the exception was thrown, but I can't understand why, exporting bcprov in an external sub-folder the problem disappear.


Solution

  • I will speculate a bit, based on your description and without any experimentation, but I hope that it will help you satisfy your curiosity.

    Java security providers that implement Cipher and some other services from javax.crypto must sign their code. If any of the signed BouncyCastle classes (or resources) were modified, the signature verification would fail, and the provider would not be available.

    My guess is that in the process of re-bundling the content of the provider, Eclipse modified some files, invalidating the signature. The most likely culprit would be a change to a manifest. You could test this by computing the hash of every resource in the good and bad versions, and see if there are any discrepancies.