SSL + SOCkET

Olá. Estou desenvolvendo um servidor socket que trabalha com SSL porém estou me deparando com a seguinte exception: signature check failed. O erro acontece no servidor ServidorSSL na Thread RecebeCliente no momento em que ele executa a instrução System.out.println(in.readLine()); Vou postar os códigos e o script de criação dos certificados, talvez o problema pode ser nos certificados. Por favor se puderem me ajudar! Qual detalhe está faltando nessa comunicação?

Exception:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: signature check failed
        at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1649)
        at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:241)
        at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:235)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1206)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:136)
        at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
        at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:893)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:632)
        at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59)
        at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202)
        at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:272)
        at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:276)
        at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:122)
        at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:212)
        at java.io.BufferedWriter.flush(BufferedWriter.java:236)
        at gatewaynutrik.ClienteSimplesSSL.run(ClienteSimplesSSL.java:81)
        at gatewaynutrik.ClienteSimplesSSL.main(ClienteSimplesSSL.java:104)
Caused by: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: signature check failed
        at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:289)
        at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:263)
        at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:184)
        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:1185)
        ... 15 more
Caused by: java.security.cert.CertPathValidatorException: signature check failed
        at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:139)
        at sun.security.provider.certpath.PKIXCertPathValidator.doValidate(PKIXCertPathValidator.java:328)
        at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:178)
        at java.security.cert.CertPathValidator.validate(CertPathValidator.java:250)
        at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:275)
        ... 22 more
Caused by: java.security.SignatureException: Signature does not match.
        at sun.security.x509.X509CertImpl.verify(X509CertImpl.java:446)
        at sun.security.provider.certpath.BasicChecker.verifySignature(BasicChecker.java:133)
        at sun.security.provider.certpath.BasicChecker.check(BasicChecker.java:112)
        at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:117)
        ... 26 more

SCRIPT DOS JKS

CERTIFICADO DO SERVIDOR

1º CRIA UM KEYSTORE VAZIOga
keytool -genkey -alias tmp -keystore truststore.jks
keytool -delete -alias tmp -keystore truststore.jks

2º Gerar uma chave privada e um certificado inicial como um keystore JKS
keytool -genkey -keyalg RSA -keysize 1024 -alias “servidor” -keystore kservidor.jks -storepass “123456” -validity 365

3º Gerar um Certificate Signing Request para uma chave em um keystore JKS.O CSR é enviado para a CA e esta devolve o certificado assinado. Ai basta importar para o keystore (kservidor.jks) com o mesmo alias (servidor) com que foi criada a chabe privada

keytool -certreq -v -alias “servidor” -keystore kservidor.jks -storepass “123456” -file servidor.csr

4º Exporta o certificado para um arquivo
keytool -export -alias “servidor” -keystore kservidor.jks -file servidor.x509

5º Importa um certificado (assinado) para o keystore
keytool -import -keystore kservidor.jks -storepass “123456” -file servidor.x509

6º Adicionar um certificado público para um keystore JKS, por exemplo, o truststore JVM
keytool -import -trustcacerts -alias “servidor” -file servidor.x509 -keystore truststore.jks

CERTIFICADO DO CLIENTE

1º CRIA UM KEYSTORE VAZIO
keytool -genkey -alias tmp -keystore truststoreCliente.jks
keytool -delete -alias tmp -keystore truststoreCliente.jks

2º Gerar uma chave privada e um certificado inicial como um keystore JKS
keytool -genkey -keyalg RSA -keysize 1024 -alias “cliente” -keystore kcliente.jks -storepass “123456” -validity 365

3º Gerar um Certificate Signing Request para uma chave em um keystore JKS.O CSR é enviado para a CA e esta devolve o certificado assinado. Ai basta importar para o keystore (kcliente.jks) com o mesmo alias (cliente) com que foi criada a chabe privada

keytool -certreq -v -alias “cliente” -keystore kcliente.jks -storepass “123456” -file cliente.csr

4º Exporta o certificado para um arquivo
keytool -export -alias “cliente” -keystore kcliente.jks -file cliente.x509

5º Importa um certificado (assinado) para o keystore
keytool -import -keystore kcliente.jks -storepass “123456” -file cliente.x509

6º Adicionar um certificado público para um keystore JKS, por exemplo, o truststore JVM
keytool -import -trustcacerts -alias “cliente” -file cliente.x509 -keystore truststoreCliente.jks

ESSE É CÓDIGO DO SERVIDOR

import com.sun.corba.se.impl.logging.UtilSystemException;
import java.net.*;
import java.io.*;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.ServerSocketFactory;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;

public class ServerSSL implements Runnable {

    private SSLServerSocket ssocket;
    private SSLServerSocketFactory factory;
    private int SERVER_PORT;

    public SSLServerSocket criaSSLServerSocket() throws Exception {
        System.setProperty("java.naming.security.protocol", "ssl");
        System.setProperty("javax.net.ssl.trustStore", "C:\\Program Files\\Java\\jdk1.6.0_22\\bin\\kservidor.jks");
        System.setProperty("javax.net.ssl.trustStorePassword", "123456");
        KeyStore ks = Utils.getKeyStore("JKS");
        ks.load(new FileInputStream("C:\\Program Files\\Java\\jdk1.6.0_22\\bin\\kservidor.jks"), "nrqi85".toCharArray());

        KeyManagerFactory kmf = Utils.getKMFactory("SunX509");
        kmf.init(ks, "123456".toCharArray());

        SSLContext contextoSSL = Utils.criaSSLContext("SSLv3");
        //CustomTrustManager[] cus = new CustomTrustManager[2979];
        contextoSSL.init(kmf.getKeyManagers(), null, null);

        ServerSocketFactory ssf = contextoSSL.getServerSocketFactory();
        SSLServerSocket servidorSSL = (SSLServerSocket) ssf.createServerSocket(SERVER_PORT);
        servidorSSL.setEnabledCipherSuites(servidorSSL.getSupportedCipherSuites());
        servidorSSL.setNeedClientAuth(false);

        return servidorSSL;
    }

    public ServerSSL(int port) {
      
    }

    public void start() throws UnknownHostException {
        SSLSocket _socket = null;
        //this.AddLista("Servidor iniciou com sucesso em " + InetAddress.getLocalHost().toString() + " porta " + SERVER_PORT);

        System.out.println("Servidor iniciou com sucesso em " + InetAddress.getLocalHost().toString() + " porta " + SERVER_PORT);
        while (true) {
            try {
                new RecebeCliente((SSLSocket) ssocket.accept()).start();
                System.out.println("Novo cliente na lista");

            } catch (Exception e) {
                System.out.println("Thread exception" + e.getMessage());
                try {
                    _socket.close();
                } catch (Exception ex) {
                    System.out.println("Erro ao fechar o SOCKET");

                }
            }
        }
    }

    public void run() {
        try {
            factory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
            try {
                this.SERVER_PORT = 2979;
                ssocket = criaSSLServerSocket();
            } catch (Exception ex) {
                Logger.getLogger(frmSever.class.getName()).log(Level.SEVERE, null, ex);
            }
            this.start();
        } catch (UnknownHostException ex) {
            Logger.getLogger(ServerSSL.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public static void main(String[] args) throws Exception {
        ServerSSL server = new ServerSSL(2979);
        server.run();
    }
}

class RecebeCliente extends Thread implements Constants {

    private SSLSocket cliente;
    private DataInputStream dis;
    private SSLSocket socket;
    private boolean done = false;
    private Thread thread;
    private String hostname;
    private User user;
    BufferedReader in;
    DataOutputStream out;
    //frmSever Server = new frmSever();

    public RecebeCliente(SSLSocket s) throws IOException, Exception {

        cliente = s;
        this.socket = cliente;
        //dis = new DataInputStream(socket.getInputStream());
        out = new DataOutputStream(cliente.getOutputStream());
        in = new BufferedReader(new InputStreamReader(cliente.getInputStream()));
        System.out.println("Novo cliente acessando.");
        System.out.println(in.readLine());

    }

    public void run() {
        try {
            out.writeUTF("Olá Cliente!");
            out.flush();
        } catch (Exception err) {
            err.printStackTrace();
            done = true;
            try {
                socket.close();
            } catch (Exception se) {
                se.printStackTrace();
            }
        }
    }
}

ESSE É O CÓDIGO DO CLIENTE

import java.io.*;
import java.net.*;
import java.security.*;
import javax.net.SocketFactory;
import javax.net.ssl.*;

public class ClienteSimplesSSL {

    private static final int HTTPS_PORT = 2979;
    private static SSLSocket socket;
    private String keystore = "C:\\Program Files\\Java\\jdk1.6.0_22\\bin\\kcliente.jks";
    private char[] password;
    private String nome;
    private String host;

    public ClienteSimplesSSL(String nome, String password, String host) {
        this.nome = nome;
        this.password = password.toCharArray();
        this.host = host;

        System.setProperty("java.naming.security.protocol", "ssl");
        System.setProperty("javax.net.ssl.trustStore", keystore);
        System.setProperty("javax.net.ssl.trustStoreType", "JKS");
        System.setProperty("javax.net.ssl.trustStorePassword", password);

        /*System.setProperty("javax.net.ssl.trustStoreType", "JKS");
        System.setProperty("javax.net.ssl.trustStore", "C:\\Program Files\\Java\\jdk1.6.0_22\\bin\\truststoreCliente.jks");
        System.setProperty("javax.net.ssl.trustStorePassword", password);*/
    }

    private SSLSocket criaSSLSocket(String host) throws Exception {

        System.setProperty("javax.net.ssl.trustStore", keystore);

        System.setProperty("javax.net.ssl.trustStorePassword", "123456");

        KeyStore ks = Utils.getKeyStore("JKS");
        ks.load(new FileInputStream(keystore), password);

        KeyManagerFactory kmf = Utils.getKMFactory("SunX509");
        kmf.init(ks, password);

        SSLContext sslcontext = Utils.criaSSLContext("SSLv3");
        sslcontext.init(kmf.getKeyManagers(), null, null);

        SSLSocketFactory ssf = sslcontext.getSocketFactory();
        SSLSocket socket = (SSLSocket) ssf.createSocket(host, HTTPS_PORT);

        return (SSLSocket) socket;
    }

    public void run() {

        try {
            socket = criaSSLSocket(host); //cria o socket SSL que o cliente utilizará
            socket.setSoTimeout(0);
            socket.setKeepAlive(true);
            ((SSLSocket) socket).setEnableSessionCreation(true);
        } catch (Exception e) {
            System.out.println("Excecao 1 lancada : " + e.getMessage());
        }

        try {



            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            out.write("Olá servidor");
            out.flush();
            
            String linha;
            StringBuffer sb = new StringBuffer();
            while ((linha = in.readLine()) != null) {
                sb.append(linha);
                sb.append("\n");
            }
            out.close();
            in.close();
            System.out.println(sb.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static void main(String argv[]) throws IOException {

        System.out.print("Informe o password para o keystore do cliente:");
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String password = in.readLine();
        ClienteSimplesSSL cliente = new ClienteSimplesSSL("Cliente 1", password, "192.168.0.225");
        cliente.run();
    }
}

E ai alguém sabe?