Testcontainers-java: Using BouncyCastle results in 'testcontainers-1.7.3.jar has unsigned entries'

Created on 17 Aug 2018  路  11Comments  路  Source: testcontainers/testcontainers-java

Hi there

Versions

Problem

After adding/using testconainers:1.8.3 to existing tests I get:
java.util.jar.JarException w.r.t. testcontainers-1.7.3.jar has unsigned entries - org/testcontainers/utility/DockerLoggerFactory.class.

Cause

Short

When executing a test using BouncyCastle:1.58 after having executed a test using testcontainers:1.8.3 the java.util.jar.JarException is thrown.

Long

This happens when I execute an existing test which exercises code that encrypts and decrypts some data using the BouncyCastle:1.58 library's PGP implementation. Whereas my implementation requires the BouncyCastle provider org.bouncycastle.jce.provider.BouncyCastleProvider.
The corresponding test doesn't depend on testcontainers, and executing it alone works.

Now, when that test is run after another test which uses testconstainers:1.8.3 the java.util.jar.JarException is thrown (see shortened sample stacktrace below for reference).

"Analysis" (my guess)

The testcontainers-1.7.3.jar (testconainers:1.8.3 seems to depend on it) shaded in the BouncyCastle library (version 1.54D).
My guess: Shading it in resulted in either stripped off or invalid signatures. (Because of Stackoverflow).

Workaround

I found that no code change to my tests could resolve the problem. In particular, I tried Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());.

I also couldn't find a way to somehow exclude the testcontainers-1.7.3.jar from the testcontainers:1.8.3 Maven dependency.

What resolved the problem for me was adding security.provider.11=org.bouncycastle.jce.provider.BouncyCastleProvider
to the used JDK 8, /jre/lib/security/java.security.

Wish

I'd be cool if adding testconainers would not conflict with any existing use of BouncyCastle in a project.
Or it'd be clear what needs to be adapted in such a project to make them work side-by-side without changing the java.security configuration of the Java installation.

Proposed solution

Instead of shading in the BouncyCastle library make it a dependency, so that it can be excluded in a Maven build. I'd imagine something like

        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>testcontainers</artifactId>
            <version>${testcontainers.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.bouncycastle</groupId>
                    <artifactId>bcprov-jdk15on</artifactId>
                </exclusion>
            </exclusions>
            <scope>test</scope>
        </dependency>

There may be better approaches, but I don't see them.

Stacktrace

org.bouncycastle.openpgp.PGPException: Exception decrypting key

Caused by: org.bouncycastle.openpgp.PGPException: Exception decrypting key
    at org.bouncycastle.openpgp.PGPSecretKey.extractKeyData(Unknown Source)
    at org.bouncycastle.openpgp.PGPSecretKey.extractPrivateKey(Unknown Source)
    ... 34 more
Caused by: java.lang.SecurityException: JCE cannot authenticate the provider BC
    at javax.crypto.Cipher.getInstance(Cipher.java:656)
    at javax.crypto.Cipher.getInstance(Cipher.java:595)
    at org.bouncycastle.jcajce.util.NamedJcaJceHelper.createCipher(Unknown Source)
    at org.bouncycastle.openpgp.operator.jcajce.OperatorHelper.createCipher(Unknown Source)
    at org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder$1.recoverKeyData(Unknown Source)
    ... 37 more
Caused by: java.util.jar.JarException: file:/C:/Users/user/.m2/repository/org/testcontainers/testcontainers/1.7.3/testcontainers-1.7.3.jar has unsigned entries - org/testcontainers/utility/DockerLoggerFactory.class
    at javax.crypto.JarVerifier.verifySingleJar(JarVerifier.java:502)
    at javax.crypto.JarVerifier.verifyJars(JarVerifier.java:363)
    at javax.crypto.JarVerifier.verify(JarVerifier.java:289)
    at javax.crypto.JceSecurity.verifyProviderJar(JceSecurity.java:164)
    at javax.crypto.JceSecurity.getVerificationResult(JceSecurity.java:190)
    at javax.crypto.Cipher.getInstance(Cipher.java:652)
    ... 41 more

Cheers,
Yves

areshading resolutioacknowledged typbug

All 11 comments

Hi @incyg,

Wow, thanks for reporting! BouncyCastle comes as a transitive dependency from docker-java, as well as Netty, but we plan to switch to something more lightweight.
In fact, there is OkHttp alternative transport already, you can turn it on with transport.type=okhttp in $HOME/.testcontainers.properties.
Could you please try it?

Hi @bsideup,
added transport.type=okhttp to my .testcontainers.properties, but doesn't help. Still getting the same error,

Cheers,
Yves

For me helped:

Security.removeProvider("BC")
Security.addProvider(new BouncyCastleProvider)

I guess it depends who adds the provider.

Can you also please try out version 1.9.1?
We switched to okhttp as default transport.

Hi @kiview

Yes, I can confirm using version 1.9.1 resolves my problem as I reported it.

(To be sure, I first reproduced the problem using version 1.8.3, and then switched only the testcontainers version from 1.8.3 to 1.9.1).

Great, problem solved. Thank you.
Yves

Hey @incyg, thanks for trying out and great to hear!

Hi.
I'm using 1.9.1 and see this issue again:

java.util.jar.JarException
testcontainers-1.9.1.jar has unsigned entries - org/testcontainers/utility/DockerLoggerFactory.class

Hi @dant3,

The latest Testcontainers version is 1.10.6.

Woops, looks like I was in the wild too long :)
Still, reproduced with 1.10.6 as well:

testcontainers-1.10.6.jar has unsigned entries - org/testcontainers/lifecycle/Startable.class

Replacing the provided like suggested above helps however.

Security.removeProvider("BC")
Security.addProvider(new BouncyCastleProvider())

Still, reproduced with 1.10.6 as well:

still needs the workaround in 1.12.5

Security.removeProvider("BC")
Security.addProvider(new BouncyCastleProvider())

And for everybody else using this workaround, make sure to use the correct import and not org.testcontainers.shaded.org.bouncycastle.jce.provider.BouncyCastleProvider

Was this page helpful?
0 / 5 - 0 ratings

Related issues

andredasilvapinto picture andredasilvapinto  路  3Comments

kiview picture kiview  路  3Comments

ayedo picture ayedo  路  3Comments

michael-simons picture michael-simons  路  3Comments

dabraham02124 picture dabraham02124  路  3Comments