3

I'm trying to download a captcha image from a specific URL because I'm working on a program to solve simple captchas. The url I'm using: https://www.mannschaftsfoto-nrw.de/rpc/captcha/Ddc3Lp5eOshwmzWfpgL4cNCTnZTcOU2T I've read many posts before and tried different things, what I'm using right now is this code:

URL url = new URL("https://www.mannschaftsfoto-nrw.de/rpc/captcha/Ddc3Lp5eOshwmzWfpgL4cNCTnZTcOU2T"); 
  InputStream in = new BufferedInputStream(url.openStream());
  ByteArrayOutputStream out = new ByteArrayOutputStream();
  byte[] buf = new byte[1024];
  int n = 0;
  while (-1!=(n=in.read(buf)))
  {
    out.write(buf, 0, n);
  }
  out.close();
  in.close();
  byte[] response = out.toByteArray();
  FileOutputStream fos = new FileOutputStream("C://captcha.jpg");
  fos.write(response);
  fos.close();

This does in fact work when I'm using a different URL like a google image, but it doesn't work for my link. I get the Exception: Exception: javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair Can this function even work, although the link doesn't end on ".png"?

Neiro
  • 41
  • 6

2 Answers2

1

I tried to execute the same program above. It worked cool and the image was downloaded in C:\captcha.jpg. Here is the code below.

So, there is no need for having .jpg at the end of the link for the image to get downloaded. I used jdk1.6.0_45.

For the SSL problem, solution is as follows,

Beginning with version 2.4.7, mod_ssl will use DH parameters which include primes with lengths of more than 1024 bits. Java 7 and earlier limit their support for DH prime sizes to a maximum of 1024 bits, however.

If your Java-based client aborts with exceptions such as java.lang.RuntimeException: Could not generate DH keypair and java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive), and httpd logs tlsv1 alert internal error (SSL alert number 80) (at LogLevel info or higher), you can either rearrange mod_ssl's cipher list with SSLCipherSuite (possibly in conjunction with SSLHonorCipherOrder), or you can use custom DH parameters with a 1024-bit prime, which will always have precedence over any of the built-in DH parameters.

To generate custom DH parameters, use the openssl dhparam 1024 command.

So, your code should work perfectly with java 8 without ssl issue.

package stack.overflow;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;

public class Testing {
    public static void main(String[] args) {
         URL url = null;
        try {
            url = new URL("https://www.mannschaftsfoto-nrw.de/rpc/captcha/Ddc3Lp5eOshwmzWfpgL4cNCTnZTcOU2T");
          InputStream in = new BufferedInputStream(url.openStream());
          ByteArrayOutputStream out = new ByteArrayOutputStream();
          byte[] buf = new byte[1024];
          int n = 0;
          while (-1!=(n=in.read(buf)))
          {
            out.write(buf, 0, n);
          }
          out.close();
          in.close();
          byte[] response = out.toByteArray();
          FileOutputStream fos = new FileOutputStream("C://captcha.jpg");
          fos.write(response);
          fos.close();
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
    }
}
Priya
  • 81
  • 3
  • It works for me now too. My compiler was just linked to an old jdk version although I updated Java just a few days ago.. Thanks for your answer anyways =) – Neiro Nov 25 '15 at 12:12
0

You need to download all the certificates/certificate chain from server using open ssl

Assuming you have OpenSSL installed (default available on Mac OS X and Linux systems) have a look at the s_client command:

openssl s_client -host google.com -port 443 -prexit -showcerts

The above command prints the complete certificate chain of google.com to stdout. Now you’ll just have to copy each certificate to a separate PEM file (e.g. googleca.pem). Finally you can import each certificate in your (Java) truststore. To import one certificate:

keytool -import -alias gca -file googleca.pem -keystore trust.jks

Now use this truststore to create a connection with the website in secure HTTP mode.

Abhash Upadhyaya
  • 717
  • 14
  • 34