Bouncy Castle in Mendix 7.3 - cannot create signature

1
Hi, I've been using the Bouncy Castle library with Mendix 7.1. In Mendix 7.3 in the release notes it says: "Runtime will not globally register the Bouncy Castle Java library in order to prevent clashes with the usage of Bouncy Castle in the user libraries" Thus I now register it myself after startup: import org.bouncycastle.jce.provider.BouncyCastleProvider; ... Security.addProvider(new BouncyCastleProvider()); Now, when I try to verify a signature ... sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), publicKey); ... I get an exception: org.bouncycastle.openpgp.PGPException: cannot create signature: Error constructing implementation (algorithm: SHA256WITHRSA, provider: BC, class: org.bouncycastle.jcajce.provider.asymmetric.rsa.DigestSignatureSpi$SHA256) at org.bouncycastle.openpgp.operator.jcajce.OperatorHelper.createSignature(Unknown Source) at org.bouncycastle.openpgp.operator.jcajce.OperatorHelper.createSignature(Unknown Source) at org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider$JcaPGPContentVerifierBuilder.build(Unknown Source) at org.bouncycastle.openpgp.PGPSignature.init(Unknown Source) Caused by: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: SHA256WITHRSA, provider: BC, class: org.bouncycastle.jcajce.provider.asymmetric.rsa.DigestSignatureSpi$SHA256) at java.security.Provider$Service.newInstance(Unknown Source) at sun.security.jca.GetInstance.getInstance(Unknown Source) at sun.security.jca.GetInstance.getInstance(Unknown Source) at java.security.Signature.getInstance(Unknown Source) at org.bouncycastle.jcajce.util.NamedJcaJceHelper.createSignature(Unknown Source) at org.bouncycastle.openpgp.operator.jcajce.OperatorHelper.createSignature(Unknown Source) at org.bouncycastle.openpgp.operator.jcajce.OperatorHelper.createSignature(Unknown Source) at org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider$JcaPGPContentVerifierBuilder.build(Unknown Source) at org.bouncycastle.openpgp.PGPSignature.init(Unknown Source) at licensing.LicenseTool.verifyData(LicenseTool.java:318) ... Caused by: java.security.AccessControlException: access denied ("java.util.PropertyPermission" "org.bouncycastle.pkcs1.not_strict" "read") at java.security.AccessControlContext.checkPermission(Unknown Source) at java.security.AccessController.checkPermission(Unknown Source) at java.lang.SecurityManager.checkPermission(Unknown Source) at java.lang.SecurityManager.checkPropertyAccess(Unknown Source) at java.lang.System.getProperty(Unknown Source) at org.bouncycastle.crypto.encodings.PKCS1Encoding$2.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at org.bouncycastle.crypto.encodings.PKCS1Encoding.useStrict(Unknown Source) at org.bouncycastle.crypto.encodings.PKCS1Encoding.<init>(Unknown Source) at org.bouncycastle.jcajce.provider.asymmetric.rsa.DigestSignatureSpi$SHA256.<init>(Unknown Source) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) at java.lang.reflect.Constructor.newInstance(Unknown Source) at java.security.Provider$Service.newInstance(Unknown Source) at sun.security.jca.GetInstance.getInstance(Unknown Source) at sun.security.jca.GetInstance.getInstance(Unknown Source) at java.security.Signature.getInstance(Unknown Source) at org.bouncycastle.jcajce.util.NamedJcaJceHelper.createSignature(Unknown Source) at org.bouncycastle.openpgp.operator.jcajce.OperatorHelper.createSignature(Unknown Source) at org.bouncycastle.openpgp.operator.jcajce.OperatorHelper.createSignature(Unknown Source) at org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider$JcaPGPContentVerifierBuilder.build(Unknown Source) at org.bouncycastle.openpgp.PGPSignature.init(Unknown Source) at licensing.LicenseTool.verifyData(LicenseTool.java:318) ... Has anyone encountered this or knows what I am doing wrong?
asked
3 answers
3

From the ticket:

R&D: The issue is caused by the fact that a named security provider approach is used. This does not comply well with a multi-classloader environment (the Mendix Runtime code also uses BouncyCastle functionality). The fix is changing that approach to an explicit security provider approach. 

In your case -->

Instead of:

import org.bouncycastle.jce.provider.BouncyCastleProvider;

Security.addProvider(new BouncyCastleProvider());

sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), publicKey);

Try this:

import org.bouncycastle.jce.provider.BouncyCastleProvider;

sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider(new BouncyCastleProvider()), publicKey);

 

answered
2

Due to the classloader structure of the Mendix Runtime it is better to not globally register security providers. So instead of doing:

Security.addProvider(new BouncyCastleProvider());

...

sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), publicKey);

Use the following approach:

sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider(new BouncyCastleProvider()), publicKey);

This gives you the same functionality with the benefit of not having to register the provider globally.

The exception you got, is that the full exception or was there more? More details are needed to find out why exactly this failed.

 

answered
1

Unfortunately I have run into this myself as well,  in Mendix 7 the classloader seems to have changed and there seem to be a few cases where the platform mixes up the libraries that are being used.

 

If you startup through eclipse you can add -verbose class loader logging in the startup parameters and see which library is used for a specific function. For me I noticed that the platform was suddenly switching to a different library (from my program files folder), I was not able to find a way around this.

 

I would recommend to startup through eclipse and add the verbose class loading parameter to the startup, this allows you to confirm which library is being used. If you run into the same problem as I was you will see the same bouncy class package but 2 different folder locations. That isn't a valid/secure solution for BC.

If you see that same behavior unfortunately the only 2 recommendations I can give you is to submit a ticket,  or use an implementation that doesn't require the 'Security.addProvider(new BouncyCastleProvider());' statement and can do explicit loading or execution.

answered