Internet Programming with Java Course

1.7 HTTPS. SSL

 

JSSE possibilities in a few examples

 

This JSSE sample code bundle provides some rudimentary examples of how the JSSE can be used to secure communications in the Java(tm) network environment.

 

The samples do require some familiarity with Java and the JSSE API, so please consult the appropriate documentation for more information.

 

JDK: http://java.sun.com/doc/

 

Also consult the JDK implementation's documentation.

 

JSSE: documentation for the JSSE API can be found in Sun's JSSE implementation or documentation bundles, or at

http://java.sun.com/products/jsse/

 

Also consult the JSSE implementation's documentation. Follow any instructions given by the vendor as to how to configure the security provider, set the classpaths (if necessary), enable the https protocol handler, define HTTPS proxy servers, and so on.

 

Example of Java Https URL reader.

 

This example illustrates using a URL to access resources on a secure site. By default, this example connects to www.verisign.com, but it can be adapted to connect to the ClassFileServer above. The URL request must be slightly modified, and you must create a host certificate for the https host being used, otherwise there will be a "HTTPS hostname wrong" error. (Note: This behaviour can be overriden by using the HostNameVerifier in the HttpsURLConnection class.)

 

If you are using Sun's reference implementation, you will need to set the System property "java.protocol.handler.pkgs" to point to the JSSE https implementation. Also, if you are behind a firewall, you will need to set "https.proxyHost" and "https.proxyPort".

 

import java.net.*;

import java.io.*;

 

import com.sun.net.ssl.internal.www.protocol.https.*;

import java.security.Security;

 

/*

* This example illustrates using a URL to access resources

* on a secure site.

*

* To use Sun's reference implementation of HTTPS protocol, Please set

* the following Java system property:

*

* java.protocol.handler.pkgs = com.sun.net.ssl.internal.www.protocol

*

* If you are running inside a firewall, please also set the following

* Java system properties to the appropriate value:

*

* https.proxyHost = <secure proxy server hostname>

* https.proxyPort = <secure proxy server port>

*

*/

 

 

public class URLReader

{

public static void main(String[] args) throws Exception

{

Security.addProvider ( new com.sun.net.ssl.internal.ssl.Provider());

System.setProperty ("java.protocol.handler.pkgs",

"com.sun.net.ssl.internal.www.protocol");

 

URL verisign = new URL("https://www.verisign.com/");

BufferedReader in = new BufferedReader(

new InputStreamReader(verisign.openStream()));

 

String inputLine;

while ((inputLine = in.readLine()) != null)

System.out.println(inputLine);

 

in.close();

}

}

 

Example of Java SSL socket client

 

This example demonstrates how to use a SSLSocket as a client to send a HTTP request and get a response from an HTTPS server. By default, this example connects to www.verisign.com, but it can easily be adapted to connect to the ClassFileServer above. (Note: The GET request must be slightly modified. See above for more information.)

 

This application assumes the client is not behind a firewall.

 

import java.net.*;

import java.io.*;

import javax.net.ssl.*;

 

import com.sun.net.ssl.internal.www.protocol.https.*;

import java.security.Security;

 

/*

* This example demostrates how to use a SSLSocket as client to

* send a HTTP request and get response from an HTTPS server.

* It assumes that the client is not behind a firewall

*/

 

public class SSLSocketClient

{

 

public static void main(String[] args) throws Exception

{

try {

 

Security.addProvider ( new com.sun.net.ssl.internal.ssl.Provider());

 

SSLSocketFactory factory =

(SSLSocketFactory)SSLSocketFactory.getDefault();

SSLSocket socket =

(SSLSocket)factory.createSocket("www.verisign.com", 443);

 

/*

* send http request

*

* Before any application data is sent or received, the

* SSL socket will do SSL handshaking first to set up

* the security attributes.

*

* SSL handshaking can be initiated by either flushing data

* down the pipe, or by starting the handshaking by hand.

*

* Handshaking is started manually in this example because

* PrintWriter catches all IOExceptions (including

* SSLExceptions), sets an internal error flag, and then

* returns without rethrowing the exception.

*

* Unfortunately, this means any error messages are lost,

* which caused lots of confusion for others using this

* code. The only way to tell there was an error is to call

* PrintWriter.checkError().

*/

socket.startHandshake();

 

PrintWriter out = new PrintWriter( new BufferedWriter(

new OutputStreamWriter(socket.getOutputStream())));

 

out.println("GET http://www.verisign.com/index.html HTTP/1.1");

out.println();

out.flush();

 

/*

* Make sure there were no surprises

*/

if (out.checkError())

System.out.println("SSLSocketClient: java.io.PrintWriter error");

 

/* read response */

BufferedReader in = new BufferedReader(

new InputStreamReader(socket.getInputStream()));

 

String inputLine;

while ((inputLine = in.readLine()) != null)

System.out.println(inputLine);

 

in.close();

out.close();

socket.close();

 

} catch (Exception e) {

e.printStackTrace();

}

}

}

 

Common problems using JSSE.

 

One of the most common problems people have in using JSSE is when the JSSE receives a certificate that is unknown to the mechanism that makes trust decisions. If an unknown certificate is received, the trust

mechanism will throw an exception saying that the certificate is untrusted. Make sure that the correct trust KeyStore is being used, and that the JSSE is installed and configured correctly.

 

In the Sun Reference Implementation, the exception error returned will be:

 

javax.net.ssl.SSLException: untrusted server cert chain

 

The SSL debug mechanism can be used to investigate such trust problems. See the implementation documentation for more information about this subject.