1

I'm using SSHJ-library in a project. SSHJ library utilized the bouncycastle crypto.

In eclipse all is good but after I use one-jar to package all in single jar package, I'm facing issues with the bouncycastle lib. The bcprov-jdk15on-1.51.jar is included in the JAR package in /lib, where is all the other libraries, as well as eg. sshj.jar.

On log I have these:

Security Provider class 'org.bouncycastle.jce.provider.BouncyCastleProvider' not found

and this

WARNING: Disabling high-strength ciphers: cipher strengths apparently limited by JCE policy

And with the functionality the SFTP connection is resulting into:

net.schmizz.sshj.transport.TransportException: Unable to reach a settlement: [diffie-hellman-group1-sha1, diffie-hellman-group-exchange-sha1] and [diffie-hellman-group-exchange-sha256]

What I have tried:

  • Installed the Java JCE into /lib/security
    • Not sure why the above message still pops up about the disabled high-strengt ciphers?
  • Tried "Security.addProvider(new BouncyCastleProvider());" in code

This is how all work "as expected":

  • By putting the "bcprov-jdk15on-1.51.jar" in to JAVA_HOME\lib\ext\
    • unfortunately this is the LAST option for me. I will have huge headache to maintain the libraries in Java version update situations.

So, clearly there is some classpath issue with the BC libary? Somewhere I read something about signed security provider library having an issues implementing, did not quite understand that one... Maybe that is the reason here too?

Any ideas how this issue is solved? Any help on this issue is appreciated, thanks!

EDIT: My build.xml with suggested code-signing implemented:

    <target name="package_x" depends="package_y">
    <!-- Create manifest file for x -->
    <delete file="MANIFEST.MF"/>
    <manifest file="MANIFEST.MF">
        <attribute name="Main-Class" value="com.simontuffs.onejar.Boot"/>
        <attribute name="One-Jar-Main-Class" value="com.some.main.class.name"/>
        <attribute name="Class-Path" value="some_other_libs lib/bcprov-jdk15on.jar ." />
    </manifest>

    <!-- Copy properties file -->
    <copy todir="${module.dist.dir}">
        <fileset dir="${module.x.build.dir}/classes">
            <include name="**/*.properties"/>
        </fileset>
    </copy>

        <signjar destDir="${basedir}/distribute/lib/" 
                alias="server" keystore="${module.x.src.dir}/keystore/myCSC.jks"
                storepass="pass"
                preservelastmodified="true">
            <path>
                <fileset dir="${basedir}/distribute/lib/" includes="bcprov-jdk15on.jar" />
            </path>
            <flattenmapper />
        </signjar>

    <!-- Construct the One-JAR file -->
    <echo message="Creating a ONE-jar package of the x files..." />

    <one-jar destfile="${module.dist.dir}/${module.x.package}" manifest="MANIFEST.MF">
        <main>
            <fileset dir="${module.x.build.dir}/classes/">
                <exclude name="x-config.properties"/>
            </fileset>
        </main>

        <lib>               
            <fileset dir="${basedir}/distribute/lib/" />
            <fileset dir="${module.common.dist.dir}" />

        </lib>
    </one-jar>

        <signjar destDir="${module.dist.dir}" 
                alias="server" keystore="${module.agent.src.dir}/keystore/myCSC.jks"
                storepass="pass"
                preservelastmodified="true">
            <path>
                <fileset dir="${module.dist.dir}" includes="**/*.jar" />
            </path>
            <flattenmapper />
        </signjar>

</target>
Jokkeri
  • 1,001
  • 1
  • 13
  • 35

2 Answers2

1

To implement a cryptographic provider is needed that the jar is signed

If your provider is supplying encryption algorithms through the Cipher KeyAgreement, KeyGenerator, Mac, or SecretKeyFactory classes, you will need to sign your JAR file so that the JCA can authenticate the code at runtime.

Bouncycastle jars are signed. You have repackaged all classes into a single jar, but you have not said that you have signed it, so I guess you did not do it. SSHJ is probably using some encryption algorithm and could not initialize bouncycastle

Options:

  • Sign your code with a code signing certificate

  • Deploy also bcprov-jdk15on-1.51.jar with your app

pedrofb
  • 37,271
  • 5
  • 94
  • 142
  • Ok, so the main issue is that I'm "one-jarring" the BC? And to be able to do so, I would have to sign the resulting one-jar package, am I correct? Is there any way to test-proof this without buying CodeSigningCert? Somehow with self-signed? – Jokkeri Jan 17 '17 at 08:16
  • 1
    Yes, the problem is the unsigned "one-jar". In the link I've provided you can see the procedure to get a code-signing certificate. Oracle issues certificates for testing (see http://www.oracle.com/technetwork/java/javase/tech/getcodesigningcertificate-361306.html#jcacodesigning). Probably a a self-signed certificate with the suitable `key-usage` will work too. It will be necessary to import the public part into the truststore of the JVM, and won't work with applets or JavaWebStart – pedrofb Jan 17 '17 at 08:33
  • I remembered that I have CodeSigningCertificate from another project but no luck with that, at least yet. I added the Ant-script of building the one-jar into original post, what am I doing wrong? According to this post http://stackoverflow.com/questions/19029575/bouncycastle-cryptography-provider-library-used-with-applet-on-java-7u40 I am signing the BC again with my in CSC. – Jokkeri Jan 17 '17 at 10:43
  • 2
    Take a look to http://www.bouncycastle.org/wiki/display/JA1/Building+the+Code+from+Source+Distributions+or+CVS _If you are trying to build a provider which works with the Sun JCE you need to have a Sun signing certificate to sign the provider jar file with._ Probably your library use the Sun JCE, so i am afraid your CodeSigningCertificate won't work and it is needed to request a codesigningcertificate to Oracle issued by _JCE Code Signing Certification Authority_ as described here http://www.oracle.com/technetwork/java/javase/tech/getcodesigningcertificate-361306.html#jcacodesigning – pedrofb Jan 17 '17 at 11:29
1

Answering my own guestion:

Two solutions:

  1. Add library to Java's lib/ext
    • this really was not a solution for me but might work for someone else.
  2. Use JDotSoft JarClassLoader
    • Simple to use and seems to provide support for adding JCE providers such as Bouncycastle.
    • added the BC-jar into main JAR by Ant build: <zipfileset dir="/build/libsToInclude/" includes="*.jar" prefix="lib/"/> and the classloader did the rest.
Jokkeri
  • 1,001
  • 1
  • 13
  • 35
  • 1
    [JDotSoft JarClassLoader](http://www.jdotsoft.com/JarClassLoader.php) solves the problem for me, too, while my usual favourite for such cases [One-Jar](http://one-jar.sourceforge.net/) had problems with the BouncyCastle JARs being signed, but my own being unsigned. Follow-up question: Does anyone know if the `JarClassLoader` class is available as a dependency on Maven Central? I did not find it there, but maybe I did not search intelligently enough. Otherwise I am thinking about uploading it myself. Copying the source code into my project is kinda ugly. – kriegaex Jul 20 '18 at 05:43
  • I couldn't find it either from maven repository. Maybe you could just upload it to Maven or first contact the creator if they wanna do themselves - email found from the site. – Jokkeri Jul 20 '18 at 06:10
  • I already did contact the creator a few hours ago and am waiting for a reply. I just wanted to know if you might know more. Thanks. – kriegaex Jul 20 '18 at 07:54
  • 1
    JDotSoft did not want to release it on Maven Central, so I did. Here is my [repo with artifact usage instructions](https://github.com/kriegaex/JarClassLoader#how-to-use-with-maven) and here is the [Maven artifact](https://search.maven.org/#artifactdetails%7Cde.scrum-master%7Cjar-class-loader%7C1.0%7Cjar). – kriegaex Aug 04 '18 at 11:17