RMI over SSL:握手失败

时间:2017-05-24 03:40:06

标签: java ssl rmi

嗨,我刚开始使用SSL,我想做一个非常简单的例子,这里是代码:

界面。

package tpfinal;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface CentralTimeService extends Remote {

    int PORT = 8844;

    long getTime() throws RemoteException;

}
  

客户端:

package tpfinal;

import java.rmi.AccessException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.rmi.ssl.SslRMIClientSocketFactory;

public class CentralTimeServiceClient {

public static void main(String[] args) {
try {
            System.setProperty("javax.net.ssl.keyStore","C:\\Users\\luciano\\workspace\\Distribuida\\bin\\keystore");
                System.setProperty("javax.net.ssl.keyStorePassword","123456");
                System.setProperty("javax.net.ssl.trustStore","C:\\Users\\luciano\\workspace\\Distribuida\\bin\\truststore");
                System.setProperty("javax.net.ssl.trustStorePassword","123456");
                Registry registry = LocateRegistry.getRegistry(null, CentralTimeService.PORT, new SslRMIClientSocketFactory());
                CentralTimeService cts = (CentralTimeService) registry.lookup("CentralTimeService");
                //Invocamos llamada RMI

long serverTime = cts.getTime();
System.out.println(serverTime);

System.out.println("Central server time is: " + SimpleDateFormat.getDateInstance().format(new Date(serverTime)));

} catch (AccessException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
}

        }

    }

服务器:

package tpfinal;

import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

import javax.rmi.ssl.SslRMIClientSocketFactory;
import javax.rmi.ssl.SslRMIServerSocketFactory;

public class CentralTimeServiceImpl extends UnicastRemoteObject implements CentralTimeService {

    protected CentralTimeServiceImpl() throws RemoteException{
        super(0, new SslRMIClientSocketFactory(), new SslRMIServerSocketFactory(null, null, true));
        System.setProperty("javax.net.ssl.keyStore","C:\\Users\\luciano\\workspace\\Distribuida\\bin\\keystore");
        System.setProperty("javax.net.ssl.keyStorePassword","123456");
        System.setProperty("javax.net.ssl.trustStore","C:\\Users\\luciano\\workspace\\Distribuida\\bin\\truststore");
        System.setProperty("javax.net.ssl.trustStorePassword","123456");
    }

    @Override
    public long getTime() throws RemoteException {
        return System.currentTimeMillis();
    }

    public static void main(String[] args) {
        try {
            Registry registry = LocateRegistry.getRegistry(null, CentralTimeService.PORT, new SslRMIClientSocketFactory());
            CentralTimeServiceImpl ctsi = new CentralTimeServiceImpl();
            registry.bind("CentralTimeService", ctsi);

            System.out.println("Central time service bound in registry");
        } catch (Exception e) {
            System.out.println("Central time error: " + e.getMessage());
            e.printStackTrace();
        }

    }



}

最后是RmiRegistry:

package tpfinal;

import java.rmi.registry.LocateRegistry;

import javax.rmi.ssl.SslRMIClientSocketFactory;
import javax.rmi.ssl.SslRMIServerSocketFactory;

public class RmiRegistry {

    public static void main(String[] args) throws Exception {
        LocateRegistry.createRegistry(CentralTimeService.PORT,new SslRMIClientSocketFactory(), new SslRMIServerSocketFactory(null, null, true));
        System.out.println("Rmi Registry running on port " + CentralTimeService.PORT);
        System.setProperty("javax.net.ssl.keyStore","C:\\Users\\luciano\\workspace\\Distribuida\\bin\\keystore");
        System.setProperty("javax.net.ssl.keyStorePassword","123456");
        System.setProperty("javax.net.ssl.trustStore","C:\\Users\\luciano\\workspace\\Distribuida\\bin\\truststore");
        System.setProperty("javax.net.ssl.trustStorePassword","123456");
        //Sleep
        Thread.sleep(Long.MAX_VALUE);
    }

}

当我执行注册表工作正常,但当我执行服务器给我这个错误,我无法弄清楚为什么。

Central time error: error during JRMP connection establishment; nested exception is: 
    javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is: 
    javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
    at sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source)
    at sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source)
    at sun.rmi.server.UnicastRef.newCall(Unknown Source)
    at sun.rmi.registry.RegistryImpl_Stub.bind(Unknown Source)
    at tpfinal.CentralTimeServiceImpl.main(CentralTimeServiceImpl.java:31)
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
    at sun.security.ssl.Alerts.getSSLException(Unknown Source)
    at sun.security.ssl.Alerts.getSSLException(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.recvAlert(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.writeRecord(Unknown Source)
    at sun.security.ssl.AppOutputStream.write(Unknown Source)
    at java.io.BufferedOutputStream.flushBuffer(Unknown Source)
    at java.io.BufferedOutputStream.flush(Unknown Source)
    at java.io.DataOutputStream.flush(Unknown Source)

请提前帮助,谢谢。

1 个答案:

答案 0 :(得分:1)

  1. 您需要移动注册表类中的所有System.setProperty()调用,以便在创建Registry之前执行它们。

  2. 您需要将服务器中的所有System.setProperty()调用移至main()方法,并在获取Registry对象之前执行它们。