Java SSLSockets:客户端和服务器上的keyStore相同,是否安全?

时间:2014-11-13 02:53:18

标签: java security ssl certificate client

所以我有一个sslServer和一个sslClient。我生成一个证书,将它放入一个keyStore,并将keyStore放入服务器的主目录。然后我将此keyStore复制到clients目录中。这样安全吗?有人只是下载我的客户端副本并获得证书/ keyStore并执行中间人攻击吗?我该如何修复此证书共享问题?如果它有帮助,这里有一些代码:

服务器:

/*This is a hidden class*/
class Server implements Runnable{
public Server(){

}
@Override
public void run() {
    DataInputStream stringGetter = null;
    try{
    KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());

    char[] password = "iamakeystore".toCharArray();
    ks.load(null, password);

    System.setProperty("javax.net.ssl.keyStore", "keyStore.jks");
    System.setProperty("javax.net.ssl.keyStorePassword", "iamakeystore");
    // Store away the keystore.
    //FileOutputStream fos = new FileOutputStream("keyStore.jks");
    //ks.store(fos, password);
    //fos.close();
    }catch(Exception e){

    }
    SSLSocket sslsocket = null;
    try {
        SSLServerSocketFactory sslserversocketfactory =
                (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
        SSLServerSocket sslserversocket =
                (SSLServerSocket) sslserversocketfactory.createServerSocket(31030);
        sslserversocket.setEnabledCipherSuites(sslserversocket.getSupportedCipherSuites());
        sslsocket = (SSLSocket) sslserversocket.accept();



        stringGetter= new DataInputStream(sslsocket.getInputStream());
        boolean done=false;
        byte input=-1;

        while(!done){

            input=stringGetter.readByte();

        switch(input){
            case 1:{

            }
        }
        }
        sslsocket.close();
    } catch (IOException e) {

        e.printStackTrace();
    }finally{
        if(stringGetter!=null){
            try {
                stringGetter.close();
            } catch (IOException e) {

                e.printStackTrace();
            }
        }
        if(sslsocket!=null){
            try {
                sslsocket.close();
            } catch (IOException e) {

                e.printStackTrace();
            }
        }

    }

}
}

客户端:

private void login(){
    System.setProperty("javax.net.ssl.keyStore", "keyStore.jks");
    System.setProperty("javax.net.ssl.keyStorePassword", "iamakeystore");
    SSLSocketFactory ssf = (SSLSocketFactory) SSLSocketFactory.getDefault();
    SSLSocket s = null;
    DataOutputStream stringSender = null;

    try {
        s=(SSLSocket) ssf.createSocket("127.0.0.1", 31030);
        s.setEnabledCipherSuites(s.getSupportedCipherSuites());
        s.startHandshake();
        stringSender= new DataOutputStream(s.getOutputStream());
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        stringSender.writeByte(1);

        stringSender.flush();
    } catch (UnknownHostException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }finally{
        if(s!=null){
            try {
                s.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}
}

2 个答案:

答案 0 :(得分:2)

  

然后我将此keyStore复制到客户端目录中。

别。

  

这样安全吗?

没有。这既不安全又毫无意义。密钥库包含私钥。因此,密钥的所有者应该是私有的。这意味着两个关键所有者,客户端和服务器,每个都应该有自己的密钥库。一个非私有的私钥会破坏它自己的目的,并使PKI和依赖它的所有内容(如TLS)完全不安全。

  

有人不能只下载我的客户端副本并获得证书/ keyStore并执行中间人攻击吗?

  

如何修复此证书共享问题?

不要分享。生成两个密钥库,两个密钥对,两个证书,并在服务器上使用一个,在客户端使用一个。不要混淆它们,不要混淆它们,不要混淆它们。

答案 1 :(得分:1)

创建两个由ca签名的证书,并将其保存到彼此的信任库中,并将私钥保存在相应的侧密钥库中,这样就可以实现相互身份验证,防御中间人攻击。