I'm trying to access website which needs a client certificate that is
on a smartcard.
Was able to get the certificate from the smartcard as
java.security.cert.Certificate object.
Also was successful in connecting the website via SSL without
certificate.
Found in the forum, that I should try to store the certificate object
in a new TrustStore and
do the SSL connection with that TrustStore:
http://forum.java.sun.com/thread.jspa?forumID=2&threadID=5118972
The communication with the smartcard reader works fine. The sample
code from sun to sign some data
with the client certificate works.
Would be great if someone could help me!
Thanks Adrian
My Code:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.security.KeyStore;
import java.security.*;
import java.security.cert.*;
import java.security.cert.Certificate;
import java.util.Enumeration;
import javax.net.ssl.*;
public class SSLSocketClientWithClientAuth {
public static void main(String[] args) throws Exception {
String host = "www.testpage.com";
int port = 443;
String path = "/login.html";
//get certificate from smartcard
String alias = "Firstname Lastname";
KeyStore scks = KeyStore.getInstance("Windows-MY");
scks.load(null, null);
Certificate cert = scks.getCertificate(alias);
//store certificate in new keystore
KeyStore ks = KeyStore.getInstance("jks");
ks.load(null, null);
ks.setCertificateEntry("cardcert", cert);
//check if certificate is in keystore -> yes it is
for (Enumeration<String> e = ks.aliases() ; e.hasMoreElements() ;)
{
String al = e.nextElement().toString();
System.out.println("CERTIFICATE: " + al);
System.out.println(ks.getCertificate(al));
}
// setup trustmanager
TrustManagerFactory tmf =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
// Setup SSLContext with above trustmanager.
SSLContext sslcont = SSLContext.getInstance("SSL");
sslcont.init(null, tmf.getTrustManagers(), new SecureRandom());
SSLSocketFactory factory = sslcont.getSocketFactory();
System.out.println("Opening connection to " + host + ":" + port +
path + "...");
SSLSocket socket = (SSLSocket) factory.createSocket(host, port);
socket.setSoTimeout(10000);
System.out.println("Starting SSL handshake...");
socket.startHandshake();
System.out.println();
System.out.println("Get Page " + host + ":" + port + path);
System.out.println();
PrintWriter out = new PrintWriter(new BufferedWriter(new
OutputStreamWriter(socket.getOutputStream())));
out.println("GET " + path + " HTTP/1.0");
out.println();
out.flush();
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();
}
}
Error:
Exception in thread "main" javax.net.ssl.SSLHandshakeException:
sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to
find valid certification path to requested target
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:
174)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:
1591)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:
187)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:
181)
at
com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:
975)
at
com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:
123)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:
516)
at
com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:
454)
at
com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:
884)
at
com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:
1096)
at
com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:
1123)
at
com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:
1107)
at
SSLSocketClientWithClientAuth.main(SSLSocketClientWithClientAuth.java:
75)
Caused by: sun.security.validator.ValidatorException: PKIX path
building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to
find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:
285)
at
sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:
191)
at sun.security.validator.Validator.validate(Validator.java:218)
at
com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:
126)
at
com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:
209)
at
com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:
249)
at
com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:
954)
... 8 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target
at
sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:
174)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:
280)
... 14 more
Robert Kochem - 26 Oct 2007 19:02 GMT
blumentarzan@gmail.com schrieb:
> I'm trying to access website which needs a client certificate that is
> on a smartcard.
[quoted text clipped - 8 lines]
> sun.security.provider.certpath.SunCertPathBuilderException: unable to
> find valid certification path to requested target
Are both certificates (server-cert and client-cert on smartcard) signed by
the same PKI?
Robert
blumentarzan@gmail.com - 28 Oct 2007 16:32 GMT
> Are both certificates (server-cert and client-cert on smartcard) signed by
> the same PKI?
>
> Robert
In that case yes. But it should also work, when they are from diffrent
CA's.
Java trust's the server certificate. SSL Connection to an other site
on the same
server but with out client cert protection works fine.
Adrian
Robert Kochem - 28 Oct 2007 19:29 GMT
blumentarzan@gmail.com schrieb:
> Java trust's the server certificate. SSL Connection to an other site
> on the same
Does Java trust the server certificate only, or the server's PKI root
certificate? I would try adding both certificates to your client trust
store and test it again.
Robert