-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Java 13 (I know...) Compatibility - XDH Key Generation (Works on Java 12) #589
Comments
Click to expand (Full Stack Trace)
|
So it turns out that JDK 13 builds have added support for X25519 and X448 to the SunJSSE provider: https://bugs.openjdk.java.net/browse/JDK-8171279 . The SunJSSE provider relies on other provider(s) to supply KeyPairGenerator, KeyFactory and KeyAgreement engines. BC provider has implementations for all these, but unfortunately SunJSSE is using java.security.spec.NamedParameterSpec (a type introduced in JDK 11) as the AlgorithmParameterSpec when initialising the X25519/X448 KeyPairGenerator, and BC doesn't recognize/support it (yet), and so the error. Lowering the priority of the BC provider should avoid this, but it would need to be moved below the SunEC provider in the list. Another option is to set the system property jdk.tls.namedGroups so that x25519 and x448 are not enabled. e.g.: Thanks for the early report of a looming issue; we'll add NamedParameterSpec support for our next release. |
Thanks for the information and fast response. So essentially we need to add an override method to Namely: @Override
public void initialize(AlgorithmParameterSpec params,
SecureRandom random) {
NamedParameterSpec nps = (NamedParameterSpec) params;
// Etc...
} If this is the right approach I could try and submit a PR. |
Well we already have that method, but it needs to also recognise NamedParameterSpec. That's relatively trivial; the complication is that NamedParameterSpec was added in JDK 11 but our jars have to run on earlier JDKs still. It's probably best to just leave it with us for now. |
Gotcha. Thanks again. |
Even with: static {
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
int requestedPosition = 2;
int actualPosition = Security.insertProviderAt(new BouncyCastleProvider(), 9999);
System.out.println("Requested to add BouncyCastleProvider at position: " + requestedPosition +
" and was actually added at position: " + actualPosition);
}
} The Bouncycastle provider is still being called and the same error is resulting. |
The |
OK, glad that's working. Moving the provider to after SunEC provider should also work; the code snippet shown above does not convince me that you tested this properly. |
Is there a way to query what "slot" the SunEC provider is in to make sure that BouncyCastle is after that number? |
Well you can see the list in your java.security config file, and even install BC that way. If it has to be programmatic, then look at the other methods available on java.security.Security class, in particular the getProviders method will return all installed providers "in their preference order". |
Okay, I think this is now fixed, I've added handling of any algorithm parameter spec that has a getName() method. This will appear in 1.64. |
Hi, using 1.64 I have the following exception:
Look like the key exchange implementation expect a XECPublicKey interface for the public key. |
@SamuelPadou I don't think that is related to this issue. |
It's not exactly the same error but it seem related. It is also linked to the added support for X25519 and X448 by JDK-8171279 in the JDK13 build. The fix above in 1.64 correct the exception in the KeyPairGenerator initialisation, but this other exception occurs 2 lines after when the XDHEPossession try to cast the public key to XECPublicKey. This interface was also introduced in JDK 11 and it look like BC doesn't support it either. I'll do some more tests and open another issue if this isn't related to this one. |
@spadou You are indeed correct that it is related. |
I think this one might also be fixed in the latest beta. https://www.bouncycastle.org/betas |
Closing as fixed. |
I am using JDK11.0.10, my BC-168 still hit this same issue. Please look into this issue. |
Just tested with Tomcat 9, Java 15 and bc 1.68:
I believe this fix made it into bc 1.69 which is currently beta - any chance of a swift release? Thanks |
The latest beta is at https://www.bouncycastle.org/betas This was fixed in 1.68 though, would you provide a list of what is in META-INF for the jar you are using? Please move comments to #881 |
Which jar? There are loads in the WEB-INF/lib directory, all related to the project. But within the bc jar, a huge list under META-INF/versions. This seems to match the bc 1.68 jars downloaded from mvnrepository. Can you be more specific so we can help further? |
I've looked further into this issue. Our project was creating a 'fat jar' of dependencies and that causes the issue with v1.68. If the bc jars are removed from the fat jar and deployed separately, the error doesn't occur. I've got no idea why this would be an issue. |
The "fat jar" concept doesn't work with the JCE/JCA - it's buried too deep in the JVM. As weird as it sounds, in some ways it does make sense - cryptography providers affect the security of the JVM, you would want extra caution around how they are handled otherwise the providing assurances, such as those around FIPS, become impossible. |
The other thing I should add is you should probably look at the BC JSEE - this is not a criticism of the JSSE provider shipped with the JVM, but Oracle announced as of Java 1.9 that they were unable to keep supporting the FIPS mode, if FEDRamp is in your future, the BCJSSE is your best choice. |
This causes java.security.InvalidKeyException: cannot identify XDH private key on Java 11 or higher. See also - bcgit/bc-java#620 - bcgit/bc-java#589 - corretto/corretto-11#168 - https://bugs.openjdk.java.net/browse/JDK-8171279
The solution to make this work in BouncyCastle makes use of the multi-release jar feature: This means the jar includes two (or more) copies of the class files, for different versions of java. If your fat jar creation logic is not multi-release jar aware, it will only include one copy of the class files, the default one. For compatibility reasons, the default ones are the ones targeting JDK8 and older (as those versions are not aware of what a multi-release jar is) |
This causes java.security.InvalidKeyException: cannot identify XDH private key on Java 11 or higher. See also - bcgit/bc-java#620 - bcgit/bc-java#589 - corretto/corretto-11#168 - https://bugs.openjdk.java.net/browse/JDK-8171279
How would you get access to the betas? |
I hit same issue on bc-fips-1.0.2.jar. Which fips version will this fix get into? @dghgit |
It's in 2.0.0. |
Some how I missed this, the betas are made available to support contract holders only - aside from the costs involved, they can't be made available for general access till we get sign off from NIST. |
Not my business, but is there any reason to concentrate on any other JDK versions besides 11 and 17 (LTS releases)? |
@dghgit I am using Java 110.20 from Amzn Corretto and org.bouncycastle:bc-fips:1.0.2.3. I have hit the same issue as above "Could not generate XDH keypair". I tried System.setProperty("jdk.tls.namedGroups", "secp256r1, secp384r1, ffdhe2048, ffdhe3072"); but it doesnt work. |
Don't the use SunJSSE. To start with it's not FIPS compliant. |
Hi, not sure what do you mean by this. I am using bc-fips-1.0.2.3 which is FIPS complaint. and marking bouncy castle as top most security provider |
See SP 800-52. |
Ok got that and hence for the same reason we are using bc-fips security provider. Am I missing something? Please elaborate. |
Are you using the BCJSSE in FIPS mode? |
Not really or may be I am not sure. I am doing the following lazy val bouncyCastle = "org.bouncycastle" % "bc-fips" % "1.0.2.3" Security.insertProviderAt(new BouncyCastleFipsProvider(), 1) And I have my other service running on SSL , it throws the mentioned error while connecting to them. |
You need to be using the BCJSSE. The Java JSSE does an internal cast to a class that does not exist as far as the FIPS module is concerned. |
It will be very helpful if you can provide how to use that with above code snippet? Because I havent specified any such. The only thing I am doing is "Security.insertProviderAt(new BouncyCastleFipsProvider(), 1)" |
how can we do it? I have the following in the code: but got the error: |
You need to be using the BCJSSE (the bctls-fips jar). |
I have in build.gradle: |
I'm not sure how that's relevant - if you look at the stack trace bctls is clearly not in use. bctls needs to be installed like a regular provider, with the appropriate priority. |
Looks like the exception is not happening anymore: after adding: |
I am not sure if this has anything to do with Bouncycastle. Java 13 has JEP 353 which rewrites (parts) of the legacy socket API. I am using Bouncycastle 1.62.
When I try to connect to Amazon AWS DynamoDB on Java 13, I get the following (partial) stack trace:
Downgrading to the latest nightly build of the Java 12 repository makes the error go away.
The actual chain of events here is that the Amazon AWS SDK is calling Apache's HTTP client which is trying to make an SSL connection. I am not 100% sure how Bouncycastle comes into it unless the only XDH provider accessible is Bouncycastle? I tried to put the provider at position 2, but it made no difference.
I believe the full stack trace where a custom AWS Lambda runtime calls a Lambda request handler, calls DynamoDB, calls Apache, calls, etc. etc. is essentially obfuscation. I think this would show up trying to make an SSL connection to Amazon's DynamoDB server that happens to use XDH key exchange. I see some changes to the
sun.security.ssl.SSLSocketImpl
classes (as well as other classes in the stack trace) new to Java 13 (most likely related to the aforementioned JEP).This could very well be a bug in the new Java socket implementation and if so I will certainly open this upstream.
Thanks for your time.
The text was updated successfully, but these errors were encountered: