Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I'm trying to authorize an old JBoss 5 running on JRockit 6 to access to a CAS server using a Let's encrypt certificate.
The problem is that Let's encrypt is not supported on JDK6 so
I added the root certificate
to the
cacerts
file.
Now the problem is that JDK 6 does not understand such big key (
java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive)
) so I tried to switch to Bouncy Castle JCE/JCA by adding
bcprov-jdk15on-1.61.jar
&
bctls-jdk15on-1.61.jar
to the
$JAVA_HOME/jre/lib/ext
folder & added
org.bouncycastle.jce.provider.BouncyCastleProvider
&
org.bouncycastle.jsse.provider.BouncyCastleJsseProvider
as first security providers in
$JAVA_HOME/jre/lib/security/java.security
file
as explained partly here
.
After a
java.lang.ArrayIndexOutOfBoundsException: 64
I switched from
SunX509
to
X.509
value for
ssl.KeyManagerFactory.algorithm
key in
java.security
file.
Now I have the following error (I think the same as
this thread on Oracle forum
):
java.security.NoSuchAlgorithmException: Algorithm ECDH not available
javax.crypto.KeyAgreement.getInstance(DashoA13*..)
org.bouncycastle.jcajce.util.DefaultJcaJceHelper.createKeyAgreement(Unknown Source)
org.bouncycastle.tls.crypto.impl.jcajce.JcaTlsCrypto.calculateKeyAgreement(Unknown Source)
org.bouncycastle.tls.crypto.impl.jcajce.JceTlsECDomain.calculateECDHAgreement(Unknown Source)
org.bouncycastle.tls.crypto.impl.jcajce.JceTlsECDH.calculateSecret(Unknown Source)
org.bouncycastle.tls.TlsECDHEKeyExchange.generatePreMasterSecret(Unknown Source)
org.bouncycastle.tls.TlsProtocol.establishMasterSecret(Unknown Source)
org.bouncycastle.tls.TlsClientProtocol.handleHandshakeMessage(Unknown Source)
org.bouncycastle.tls.TlsProtocol.processHandshakeQueue(Unknown Source)
org.bouncycastle.tls.TlsProtocol.processRecord(Unknown Source)
org.bouncycastle.tls.RecordStream.readRecord(Unknown Source)
org.bouncycastle.tls.TlsProtocol.safeReadRecord(Unknown Source)
org.bouncycastle.tls.TlsProtocol.blockForHandshake(Unknown Source)
org.bouncycastle.tls.TlsClientProtocol.connect(Unknown Source)
org.bouncycastle.jsse.provider.ProvSSLSocketDirect.startHandshake(Unknown Source)
org.bouncycastle.jsse.provider.ProvSSLSocketDirect.startHandshake(Unknown Source)
sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434)
sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:167)
sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1031)
sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230)
org.jasig.cas.client.validation.Saml11TicketValidator.retrieveResponseFromServer(Saml11TicketValidator.java:216)
But by looking at org.bouncycastle.jcajce.provider.asymmetric.EC
's sources such KeyAgreement should be correctly set by org.bouncycastle.jce.provider.BouncyCastleProvider
.
But effectively, as it is the org.bouncycastle.jsse.provider.BouncyCastleJsseProvider
which is used when creating a https client, this provider doesn't register this algorithm and I don't know how to do this.
Someone knows how to workaround this?
I have also tried to declare those jars as dependencies to my war and explicitely instanciate them like this:
static {
org.bouncycastle.jce.provider.BouncyCastleProvider bcp = new org.bouncycastle.jce.provider.BouncyCastleProvider();
java.security.Security.insertProviderAt(bcp, 1);
org.bouncycastle.jsse.provider.BouncyCastleJsseProvider bcjp = new org.bouncycastle.jsse.provider.BouncyCastleJsseProvider(bcp);
java.security.Security.insertProviderAt(bcjp, 1);
But then, I have this stack that seems to be linked to a problem in JBoss:
java.lang.SecurityException: JCE cannot authenticate the provider BC
javax.crypto.Cipher.getInstance(DashoA13*..)
org.bouncycastle.jcajce.util.ProviderJcaJceHelper.createCipher(Unknown Source)
org.bouncycastle.tls.crypto.impl.jcajce.JcaTlsCrypto.hasEncryptionAlgorithm(Unknown Source)
org.bouncycastle.tls.TlsUtils.isSupportedCipherSuite(Unknown Source)
org.bouncycastle.tls.TlsUtils.getSupportedCipherSuites(Unknown Source)
org.bouncycastle.jsse.provider.ProvTlsClient.getSupportedCipherSuites(Unknown Source)
org.bouncycastle.tls.AbstractTlsClient.init(Unknown Source)
org.bouncycastle.tls.TlsClientProtocol.connect(Unknown Source)
org.bouncycastle.jsse.provider.ProvSSLSocketDirect.startHandshake(Unknown Source)
org.bouncycastle.jsse.provider.ProvSSLSocketDirect.startHandshake(Unknown Source)
sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434)
sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:167)
sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1031)
sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230)
org.jasig.cas.client.validation.Saml11TicketValidator.retrieveResponseFromServer(Saml11TicketValidator.java:216)
Caused by: java.util.jar.JarException: Cannot parse jar:file:/opt/jboss-5.1.0.GA/server/default/deploy/myapp.war/WEB-INF/lib/bcprov-jdk15on-1.61.jar!/
javax.crypto.SunJCE_c.a(DashoA13*..)
javax.crypto.SunJCE_b.b(DashoA13*..)
javax.crypto.SunJCE_b.a(DashoA13*..)
javax.crypto.Cipher.getInstance(DashoA13*..)
org.bouncycastle.jcajce.util.ProviderJcaJceHelper.createCipher(Unknown Source)
org.bouncycastle.tls.crypto.impl.jcajce.JcaTlsCrypto.hasEncryptionAlgorithm(Unknown Source)
org.bouncycastle.tls.TlsUtils.isSupportedCipherSuite(Unknown Source)
org.bouncycastle.tls.TlsUtils.getSupportedCipherSuites(Unknown Source)
org.bouncycastle.jsse.provider.ProvTlsClient.getSupportedCipherSuites(Unknown Source)
org.bouncycastle.tls.AbstractTlsClient.init(Unknown Source)
org.bouncycastle.tls.TlsClientProtocol.connect(Unknown Source)
org.bouncycastle.jsse.provider.ProvSSLSocketDirect.startHandshake(Unknown Source)
org.bouncycastle.jsse.provider.ProvSSLSocketDirect.startHandshake(Unknown Source)
sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434)
sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:167)
sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1031)
sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230)
org.jasig.cas.client.validation.Saml11TicketValidator.retrieveResponseFromServer(Saml11TicketValidator.java:216)
In case, I have opened the issue #514 on BouncyCastle GitHub.
What you are seeing is consistent with the BouncyCastle JCE Provider not being registered. Hence the search for the ECDH Agreement is not finding it in the JCE search path.
To register the Provider dynamically simply add the following lines to your code
Security.addProvider(new BouncyCastleProvider());
Security.addProvider(new BouncyCastleJsseProvider());
as per the BouncyCastle Specifications section 6.1 and the test sample code BouncyCastle JSSE Test Code
I suspect that you are not correctly initiating the environment
–
–
–
–
–
This problem was solved in https://github.com/bcgit/bc-java/issues/514 by anthony-o as it was caused by a re-packaging issue.
However, that solution did not work for me as my bouncycastle jars are not repackaged into shade/fat jars
Here is how I solved the issue: https://stackoverflow.com/a/59845413/497378
(I am not sure of the etiquette of posting link to answers from another stackoverflow question so please delete if not appropriate)
java.lang.SecurityException: JCE cannot authenticate the provider BC
I get the same error (and the JAR was directly from Maven, no repackaging was in place), I think because starting in BC 1.61 release JARs are signed using a more recent signature algorithm (or root certificate) that Java 6 is unable to verify.
By downgrading BC to 1.60 I managed to connect to a SNI-enabled TLS server (which wasn't reachable usually by Java 6). I used the following Maven dependency:
<dependency groupId="org.bouncycastle" artifactId="bctls-jdk15on" version="1.60"/>
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.