I am testing a Java application. I am trying to start an SSL handshake using DH ciphersuite. but I am getting the following error:
java.lang.RuntimeException: Could not generate DH keypair
Some people have suggested BouncyCastle
, but many people have reported errors with it, so I am not encouraged to use it if there is another alternative.
One have suggested downloading Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files
from http://www.oracle.com/technetwork/java/javase/downloads/index.html. I did replaced the following two files java.security
and java.policy
in C:\Program Files (x86)\Java\jre7\lib\security
. Note that I also noticed that I have Java\jre7\security
installed in: Program Files (x86)
and Program Files
and I replaced both. But, I still see the same error.
Is there any workaround for this error ?
EDIT: The stack trace:
javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
at sun.security.ssl.SSLSocketImpl.handleException(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at MyClass.MyClass.myFunction(MyProg.java:78)
at MyClass.MyClass.main(MyClass.java:233)
Caused by: java.lang.RuntimeException: Could not generate DH keypair
at sun.security.ssl.DHCrypt.<init>(Unknown Source)
at sun.security.ssl.ClientHandshaker.serverKeyExchange(Unknown Source)
at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
at sun.security.ssl.Handshaker.processLoop(Unknown Source)
at sun.security.ssl.Handshaker.process_record(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
... 4 more
Caused by: java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive)
at com.sun.crypto.provider.DHKeyPairGenerator.initialize(DHKeyPairGenerator.java:120)
at java.security.KeyPairGenerator$Delegate.initialize(Unknown Source)
... 11 more
EDIT2: My code is acting as a client trying to initiate SSL handshake with a remote server (website). I set the client's cipher suite list to:
{
"TLS_ECDHE_RSA_WITH_RC4_128_SHA",
"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
"TLS_ECDHE_RSA_WITH_NULL_SHA",
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA256",
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
"SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
"SSL_DHE_RSA_WITH_DES_CBC_SHA",
"SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"
};
All ciphersuites in the client's list are supported by Java. How can configure the Java client to support initiating an SSL handshake when the server offers long DH keys ?
Yes, basically dupe of #6851461 also #9162249 and #10687200. Unlimited strength policy is NOT the solution.
The prime size for DHE (and other DH) in SSL/TLS client is and must be set from the parameters received from the server, the client can't choose something different. (That's the ClientHandshaker.serverKeyExchange in the stacktrace.)
You already have ECDHE-RSA (which works okay in Java 7, or 6 if you add an ECC provider such as but not necessarily BouncyCastle) prioritized over DHE-RSA, and the server didn't choose it. You aren't offering plain-RSA; if you are willing to go without Forward Secrecy and the server is also, try adding at least some suites like _RSA_WITH_AES_128_CBC_SHA _RSA_WITH_RC4_128_SHA before (or instead of) the _DHE_RSA ones.
Another possibility is to ask the server operator(s) to use DH 1024-bit, if they're willing and permitted. It's not actually broken yet, but it is prohibited by some important standards.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With