Java SSL DH Keypair Generation - Core Size Error

I am currently embedding Reddit OAuth2 login in my web application. Shaking hands and a token works fine when testing locally, but when starting on the server (located on the DIY OpenShift Cartridge), the following error occurs:

java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive) 

This is the result.

 java.lang.RuntimeException: Could not generate DH keypair 

I worked most of the day and found various solutions, from changing the Java version to using BouncyCastle. However, I use the Scribe library, so I don’t think I can implement BouncyCastle without overlaying and changing the scribe’s base, what kind of defeat it has in mind.

The JCE Unlimited Strength installation also appeared, but I can’t do it on OpenShift because there is no root access (maybe it can force one of their team to do this).

Used versions of java (taken from java -version ):

Local Test Machine:

 java version "1.7.0_51" OpenJDK Runtime Environment (IcedTea 2.4.4) (7u51-2.4.4-1ubuntu1) OpenJDK 64-Bit Server VM (build 24.45-b08, mixed mode) 

OpenShift Server:

 java version "1.7.0_51" OpenJDK Runtime Environment (rhel-2.4.4.1.el6_5-i386 u51-b02) OpenJDK Server VM (build 24.45-b08, mixed mode) 

I do not understand what I can do to solve this problem. I hope I'm stupid or don't understand something, so any possible solutions will be great!

-

EDIT 1

Request code that returns an error (using Scribe, as I mentioned, there may not be many). Token endpoint https://ssl.reddit.com/api/v1/access_token uses POST. As I said above, this works on my test machine.

 OAuthRequest request = new OAuthRequest(getAccessTokenVerb(), getAccessTokenEndpoint()); request.addHeader("Authorization", "Basic" +Base64.encode((config.getApiKey()+":"+config.getApiSecret()).getBytes())); request.addBodyParameter("state", "none"); request.addBodyParameter(OAuthConstants.SCOPE, config.getScope()); request.addBodyParameter(OAuthConstants.CLIENT_ID, config.getApiKey()); request.addBodyParameter(OAuthConstants.REDIRECT_URI, config.getCallback()); request.addBodyParameter(OAuthConstants.CODE, verifier.getValue()); request.addBodyParameter("grant_type", "authorization_code"); Response response = request.send(); // Errors here from Request.createConnection in the Scribe code return getAccessTokenExtractor().extract(response.getBody()); 
+6
source share
4 answers

First, "Unlimited Strength" does not matter here. This will fix a completely different problem, due to which you cannot use encryption sets using AES-256 (and if a supporter insists on them, this cannot be a handshake at all). In addition, the JVM bitrate does not matter; this (not very well-founded) restriction on DH is in the run-everywhere bytecode in SunJCE.

You can use BouncyCastle as a cryptographic provider without changing the code that makes SSL connections (in your case Scribe), but from what I read while creating BC, the preferred provider causes other problems. If you want to try anyway, put bcprov-version.jar in JRE / lib / exit and edit JRE / lib / security / java.security; or put it somewhere in your classpath and get the java.security.Security.insertProviderAt initialization code (new org.bouncycastle.jce.provider.BouncyCastleProvider (), position);

I suggest starting with why your local system is working. When I try ssl.reddit.com with openssl, it supports both ECDHE-RSA (with P-256) and DHE-RSA with dh 2048 bits. Suncle Java 7 supports and prefers ECDHE, and I would expect OpenJDK to work as well, but maybe not, and maybe not; I know that RedHat until recently lowered ECC in its rpms of openssl, and that would not surprise me if they did it in openjdk as well. If you compile and run the following command (using ssl.reddit.com 443), it will tell you which package will be negotiated on your system using all the default SSL settings for your JRE (which I expect and hope that Scribe will also use) :

 //nopackage DThompson 2012.08.13b import java.net.InetSocketAddress; import java.net.Socket; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; public class JustBConnectSSL { /* (optionally bind and) just make SSL connection, for testing reach and trust * uses default providers, truststore (normally JRE/lib/security/[jsse]cacerts), * and keystore (normally none), override with -Djavax.net.ssl.{trust,key}Store* */ public static void main (String[] args) throws Exception { if( args.length < 2 ){ System.out.println ("Usage: tohost port [fromaddr [fromport]]"); return; } Socket sock = SSLSocketFactory.getDefault().createSocket(); if( args.length > 2 ) sock.bind (new InetSocketAddress (args[2], args.length>3? Integer.parseInt(args[3]): 0)); sock.connect (new InetSocketAddress (args[0], Integer.parseInt(args[1]))); System.out.println (sock.getInetAddress().getHostName() + " = " + sock.getInetAddress().getHostAddress()); ((SSLSocket)sock).startHandshake(); System.out.println ("connect okay " + ((SSLSocket)sock).getSession().getCipherSuite()); } } 

If the test receives _DHE_RSA_something, the cryptography providers in your JRE should be different from Suncle, either modified by Ubuntu, or some configuration or patch on your system. If the test receives _ECDHE_RSA_something, but OpenShift does not, they can somehow disable ECC / ECDHE. If they can do it best (ECDHE-P-256 is at least safe and probably more effective than DH-2048). Otherwise, until Oracle fixes this (apparently at 8), the only thing I can rely on is to disable DHE packets (and return to a simple RSA, which may be unsafe for the NSA); this is the simplest code that actually creates an SSLSocket, but if Scribe (for example, most java web clients) uses the URL → HttpsUrlConnection with its default SSLSocketFactory, you can replace the modified factory, which changes the EnabledCiphers list by question lines # 6851461 (although for host with a good public certificate you don’t need user trust parts for this solution).

+6
source

I know that it is very late to answer this, but I struggled with a similar problem, and then solved it. My solution for MAC-OS.

  • Install the Bouncy Castle jar from http://www.bouncycastle.org/latest_releases.html , in / Library / Java / JavaVirtualMachines // Contents / Home / JRE / Library / ext
  • change the java.security file add the line below security.provider.2 = org.bouncycastle.jce.provider.BouncyCastleProvider and then reorder all the other providers that you may have.
  • voila
+2
source

I solved the problem with oracle java 8 by switching to the bouncycastle provider for ssl / tls:

  • Added bouncycastle to my project

     <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.54</version> </dependency> 
  • Before I make any SSL material, I will add the BouncyCastle provider as the first provider to the list:

     Security.insertProviderAt(new BouncyCastleProvider(),1); 

It's all. Now my connections to sites with 4096-bit DH parameters work as expected (I use Apache HTTP Client). This should also work with jdk 7.

+1
source

Not sure if that matters, but the OpenJDK version running on OpenShift is 32 bits, you can view it using System.getProperty ("sun.arch.data.model") in your code.

I wrote a quick class to simply output the bit-bit and compile it to the OpenShift mechanism, and run it and get 32

 class Test { public static void main(String[] args) { System.out.println(System.getProperty("sun.arch.data.model")); } } 
0
source

All Articles