certifikat til SSL/TLS forbindelse
Hej,Det er lykkedes mig at lave en klient/server løsning hvor man fra serveren kan hente intranetsider hos klienten.
Jeg forsøger nu med at lave en krypteret SSL/TLS forbindelse med authentifikation således at forbindelsen kun kan oprettes mellem indhavere af de rette certifikater.
Jeg gå ud fra at nedenstående kode vil fungere så snart jeg får genereret certifikatet korrekt. Jeg har forsøgt flg. med keytool:
keytool -genkeypair -alias peter -keystore testkeys01 -keyalg rsa
Jeg placerer samme fil testkeys01 i klientapplikations mappe (c:/xxx/java2/socket_client) og i serverapplikations mappe (c:/xxx/java2/socket_server).
Når jeg prøver det af gør jeg flg.
1. starter server.
2. starter klient.
3. skriver i servers prompt f.eks. http://intranet.xxx.dk
Har jeg misforstået noget vedr. anvendelse af den genererede certifikatfil. Jeg regner med at jeg med syntaksen (keytool -genkeypair -alias peter -keystore testkeys01 -keyalg rsa) får anvender public/private key.
Svar mig venligst hvad jeg gør galt.
jeg får udløst flg. fejl hos klient:
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(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.AppInputStream.read(Unknown Source)
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at java.io.BufferedReader.fill(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at EchoClient.main(EchoClient.java:51)
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(Unknown Source)
at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
at sun.security.validator.Validator.validate(Unknown Source)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(Unknown Source)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
... 16 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
at java.security.cert.CertPathBuilder.build(Unknown Source)
... 22 more
og flg fejl hos server:
Exception in thread "main" javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.checkEOF(SSLSocketImpl.java:1173)
at com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:65)
at sun.nio.cs.StreamDecoder$CharsetSD.readBytes(StreamDecoder.java:411)
at sun.nio.cs.StreamDecoder$CharsetSD.implRead(StreamDecoder.java:453)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:183)
at java.io.InputStreamReader.read(InputStreamReader.java:167)
at java.io.BufferedReader.fill(BufferedReader.java:136)
at java.io.BufferedReader.readLine(BufferedReader.java:299)
at java.io.BufferedReader.readLine(BufferedReader.java:362)
at sslserver.main(sslserver.java:43)
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:150)
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:117)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1584)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:866)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1030)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:622)
at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59)
at sun.nio.cs.StreamEncoder$CharsetSE.writeBytes(StreamEncoder.java:336)
at sun.nio.cs.StreamEncoder$CharsetSE.implFlushBuffer(StreamEncoder.java:404)
at sun.nio.cs.StreamEncoder$CharsetSE.implFlush(StreamEncoder.java:408)
at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:152)
at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:213)
at java.io.BufferedWriter.flush(BufferedWriter.java:236)
at java.io.PrintWriter.newLine(PrintWriter.java:410)
at java.io.PrintWriter.println(PrintWriter.java:559)
at java.io.PrintWriter.println(PrintWriter.java:670)
at sslserver.main(sslserver.java:41)
Min kode ser ud som flg.
Klientkode:
import java.io.*;
import java.net.*;
import javax.net.ssl.*;
import javax.security.cert.X509Certificate;
import java.security.KeyStore;
public class EchoClient {
public static void main(String[] args) throws IOException {
SSLSocket echoSocket = null;
PrintWriter out = null;
BufferedReader in = null;
String userInput;
SSLSocketFactory sslFact = null;
try {
SSLContext ctx;
KeyManagerFactory kmf;
KeyStore ks;
char[] passphrase = "password01".toCharArray();
ctx = SSLContext.getInstance("TLS");
kmf = KeyManagerFactory.getInstance("SunX509");
ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("testkeys01"), passphrase);
kmf.init(ks, passphrase);
ctx.init(kmf.getKeyManagers(), null, null);
sslFact = ctx.getSocketFactory();
}catch(Exception e){}
try {
echoSocket =(SSLSocket)sslFact.createSocket("172.24.22.114", 8024);
out = new PrintWriter(echoSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println(".......");
System.exit(1);
} catch (IOException e) {
System.err.println(".......");
System.exit(1);
}
String linestr="";
while ((userInput = linestr) != null)
{
linestr=in.readLine();
System.out.println(linestr);
out.println("klient svar:" + new getPage().getPage(linestr));
out.flush();
}
out.close();
in.close();
echoSocket.close();
}
}
Serverkode:
import java.net.*;
import java.security.KeyStore;
import java.io.*;
import java.io.*;
import javax.net.ServerSocketFactory;
import javax.net.ssl.*;
public class sslserver {
static SSLServerSocket serverSocket = null;
static SSLSocket clientSocket=null;
public static void main(String[] args) throws IOException {
SSLServerSocketFactory sslSrvFact = (SSLServerSocketFactory) getServerSocketFactory();
try {
serverSocket =(SSLServerSocket)sslSrvFact.createServerSocket(8024);
} catch (IOException e) {
System.err.println("Could not listen on port: 4444.");
System.exit(1);
}
System.out.println("OK");
try {
clientSocket = (SSLSocket)serverSocket.accept();
} catch (IOException e) {
System.err.println(e.getLocalizedMessage()); System.exit(1);
}
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
BufferedReader inx=null;
inx = new BufferedReader(new InputStreamReader(System.in));
String userInput;
while ((userInput = inx.readLine()) != null)
{
out.println(userInput);
out.flush();
System.out.println(in.readLine());
}
out.close();
in.close();
clientSocket.close();
serverSocket.close();
}
private static ServerSocketFactory getServerSocketFactory() {
SSLServerSocketFactory ssf = null;
try {
// set up key manager to do server authentication
SSLContext ctx;
KeyManagerFactory kmf;
KeyStore ks;
char[] passphrase = "password01".toCharArray();
ctx = SSLContext.getInstance("TLS");
kmf = KeyManagerFactory.getInstance("SunX509");
ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("testkeys01"), passphrase);
kmf.init(ks, passphrase);
ctx.init(kmf.getKeyManagers(), null, null);
ssf = ctx.getServerSocketFactory();
return ssf;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
