1) Create your keys and certificate. I tried both 'keytool' and IBM's
KeyMan to do this (KeyMan is easier, but more work to obtain, as you need
to register, etc...). Using keytool from a command prompt you need to
enter two commands - the first one creates the keystore file with the
keys, the second certifies it (self-certification, ok for testing). The
most important thing is that the name of the machine you will be using the
certificate on matches what you specify (in the example below, my machine
is called 'serverX'):
keytool -genkey -dname "CN=serverX, OU=IT, O=JPC, C=GB" -alias serverX
-keypass password -keystore serverX.cer -storepass password -keyalg "RSA"
-storetype "PKCS12" -provider sun.security.provider.Sun
keytool -selfcert -alias serverX -keystore serverX.cer -storepass password
-storetype "PKCS12"
The keystore file has now been created and self-certified: in this example
it is called 'serverX.cer' and was saved in the current directory. There
are two passwords: one for the keys and one to access the keystore. I set
them both to 'password' for testing. The name of the keystore file
('serverX.cer') is not important, I just used that for consistency.
2) To prevent warnings in a browser, add the keystore to the 'Trusted Root
Certification Authorities' on your computer. In Windows XP, I just used
Internet Options (via IE7 or Control Panel - Internet Options). On the
'Content' tab, click 'Certificates', then go to 'Trusted Root
Certification Authorities' tab, click 'Import...' and follow the steps to
import your keystore file (in my example, 'serverX.cer'). It will give
warnings about not being verified, which is ok for testing (but it must be
properly signed for production).
3) In order for Java security to recognise the certificate, it needs to be
added to
This is important when you use a Restlet client to connect to the server
via HTTPS (but it did not seem to be needed by my browser - it needed the
IE options update described in point 2). On my system, 'cacerts' is
"C:\Program Files\Java\jre6\lib\security\cacerts". I had some trouble
adding my 'serverX' certificate to it, but the following keytool commands
work if you know the password for cacerts ('changeit' is the default I
believe):
keytool -export -alias serverX -file serverX.jks -storetype "PKCS12"
-keystore serverX.cer -keypass password
keytool -import -alias serverX -file serverX.jks -noprompt -trustcacerts
-keystore "C:\Program Files\Java\jre6\lib\security\cacerts"
(when prompted for password give ‘chageit’)
The first command exports the certificate from PKCS12 format into X.509
(JKS) format, which is what cacerts needs. In my case, I had to use
KeyMan to set the password for the 'cacerts' file (I set it back to the
default of 'changeit'), so when I ran 'keytool -import ...' I could enter
the correct password. There may be a better/easier way to do this.
4) In your Java Restlet server program, in addition to the standard
Restlet jar files, you also need jar files for HTTPS. The only HTTPS
connector I could get to work correctly was 'Simple', which uses these jar
files:
lib/com.noelios.restlet.ext.simple_3.1.jar
lib/org.simpleframework_3.1/org.simpleframework.jar
lib/com.noelios.restlet.ext.ssl.jar
lib/org.jsslutils_0.5/org.jsslutils.jar
(Grizzly compiled and ran, but gave inconsistent results - appeared to be
missing requests; Jetty threw an error saying it couldn't register
'AjpServerHelper').
5) Your Restlet server code should then look something like this:
package com.jpc.samples;
import org.restlet.Component;
import org.restlet.Server;
import org.restlet.data.Parameter;
import org.restlet.data.Protocol;
import org.restlet.util.Series;
public class SampleServer {
public static void main(String[] args) throws Exception {
// Create a new Component.
Component component = new Component();
// Add a new HTTPS server listening on port 8183
Server server = component.getServers().add(Protocol.HTTPS, 8183);
Series
parameters.add("sslContextFactory",
"com.noelios.restlet.ext.ssl.PkixSslContextFactory");
//use com.noelios.restlet.util.DefaultSslContextFactory instead of PkixSslContextFactory
parameters.add("keystorePath", "
parameters.add("keystorePassword", "password");
parameters.add("keyPassword", "password");
parameters.add("keystoreType", "PKCS12");
// Attach the sample application.
component.getDefaultHost().attach("", new SampleApplication());
// Start the component.
component.start();
}
}
The HTTP examples all show
'component.getContext().getParameters().add(...) but this doesn't seem to
work for any HTTPS connectors. Using the
server.getContext().getParameters().add(...) does work but this doesn't
seem to be clearly documented anywhere.
If everything works, you should get a console message like this when you
start the server:
21-Nov-2008 00:08:44 com.noelios.restlet.ext.simple.SimpleServerHelper
start
INFO: Starting the Simple server
6) You can test it using a browser, going to https://serverX:8183/
7) If you want to write a Restlet client program you need to add the
following jar file (which has an HTTPS client connector):
com.noelios.restlet.ext.net.jar
8) Your Restlet client code then looks something like this:
package com.jpc.samples;
import java.io.IOException;
import org.restlet.Client;
import org.restlet.data.Form;
import org.restlet.data.Protocol;
import org.restlet.data.Reference;
import org.restlet.data.Response;
import org.restlet.resource.Representation;
public class SampleClient {
public static void main(String[] args) throws IOException {
// Define our Restlet HTTP client.
Client client = new Client(Protocol.HTTPS);
// The URI of the resource "list of items".
Reference samplesUri = new Reference("https://serverX:8183/sample");
// Create 9 new items
for (int i = 1; i < 10; i++)
{
Sample sample = new Sample(Integer.toString(i), "sample " + i, "this
is sample " + i + ".");
Reference sampleUri = createSample(sample, client, samplesUri);
if (sampleUri != null) {
// Prints the representation of the newly created resource.
get(client, sampleUri);
}
}
// Prints the list of registered items.
get(client, samplesUri);
}