Search code examples
javaspringmavenbouncycastlesshj

"JCE cannot authenticate the provider BC" when using sshj


I am trying to use the sshj library to create an SFTP client in an existing project of my company. However if I create the SSHClient instance I get the error message:

[main] INFO net.schmizz.sshj.common.SecurityUtils - Registration of Security Provider 'org.bouncycastle.jce.provider.BouncyCastleProvider' unexpectedly failed
java.lang.SecurityException: JCE cannot authenticate the provider BC
    at javax.crypto.JceSecurity.getInstance(JceSecurity.java:118)
    at javax.crypto.KeyAgreement.getInstance(KeyAgreement.java:270)
    at net.schmizz.sshj.common.SecurityUtils.registerSecurityProvider(SecurityUtils.java:88)
    at net.schmizz.sshj.common.SecurityUtils.register(SecurityUtils.java:267)
    at net.schmizz.sshj.common.SecurityUtils.isBouncyCastleRegistered(SecurityUtils.java:245)
    at net.schmizz.sshj.DefaultConfig.<init>(DefaultConfig.java:79)
    at net.schmizz.sshj.SSHClient.<init>(SSHClient.java:134)
[... junit stacktrace ...]
Caused by: java.util.jar.JarException: Class is on the bootclasspath
    at javax.crypto.JarVerifier.verify(JarVerifier.java:286)
    at javax.crypto.JceSecurity.verifyProviderJar(JceSecurity.java:164)
    at javax.crypto.JceSecurity.getVerificationResult(JceSecurity.java:190)
    at javax.crypto.JceSecurity.getInstance(JceSecurity.java:114)
    ... 40 more
[main] INFO net.schmizz.sshj.common.SecurityUtils - BouncyCastle not registered, using the default JCE provider
[main] INFO net.schmizz.sshj.transport.random.JCERandom - Creating new SecureRandom.

The application uses maven to include dependencies and I added it like this:

<dependency>
  <groupId>com.hierynomus</groupId>
  <artifactId>sshj</artifactId>
  <version>0.27.0</version>
</dependency>

The sshj library includes the bouncycastle (BC) dependencies to bcpkix-jdk15on v1.60 and bcprov-jdk15on v1.60 and I've tried the following solutions:

  1. Add the BC provider on my own, include the sshj and BC JARs directly as library and use the provided scope in maven as stated here. The provider is then added correctly but still fails with the error message from above.
  2. Place the BC JARs in the jre/lib/ext folder.
  3. Modify the java.security file as stated here.
  4. Check if there is another BC version on the classpath as stated here.

However if I create a fresh project and include sshj everything is working just fine and as expected. I compared the commands which execute my junit test which crates the SSHClient and in both projects I can find the sshj JAR and the BC JARs included in the -classpath.

I am fairly new to maven and spring so I might be missing something obviously why everything is fine in a fresh project and not in the existing one, but I just can't figure it out.

If you need any more information I will gladly provide them!


Solution

  • There are 2 classpaths in Java, the bootclasspath and the regular classpath. The bootclasspath is where java.* and javax.* are located (jre/lib/rt.jar). But because that is not loaded by the system classloader, it is not supported to drop signed/verified jars in there. You need to ensure that the BouncyCastle jars are on the regular classpath (as specified using the -classpath option in the JRE/JDK