Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用Netty的单向SSL身份验证_Java_Ssl_Netty_Tls1.2 - Fatal编程技术网

Java 使用Netty的单向SSL身份验证

Java 使用Netty的单向SSL身份验证,java,ssl,netty,tls1.2,Java,Ssl,Netty,Tls1.2,我正在尝试使用Netty构建一个单向身份验证套接字服务器 首先,我使用keytool为服务器和客户端生成密钥库、自签名证书和信任库,并在服务器/客户端中编写了一些代码,SSL身份验证正在工作 这是我的问题: 有没有什么方法我不需要将信任库添加到我的客户机,我只需要将密钥库添加到我的服务器,它仍然可以正常工作?我认为单向身份验证意味着只有服务器持有证书 以下是我在服务器/客户端中编写的内容,以添加到目前为止的SslHandler: 服务器: private void addSslHandlerOn


我正在尝试使用Netty构建一个单向身份验证套接字服务器
首先,我使用keytool为服务器和客户端生成密钥库、自签名证书和信任库,并在服务器/客户端中编写了一些代码,SSL身份验证正在工作

这是我的问题:
有没有什么方法我不需要将信任库添加到我的客户机,我只需要将密钥库添加到我的服务器,它仍然可以正常工作?我认为单向身份验证意味着只有服务器持有证书

以下是我在服务器/客户端中编写的内容,以添加到目前为止的SslHandler:
服务器:

private void addSslHandlerOneWay(SocketChannel ch) throws Exception {
    SSLContext sslContext = SSLContext.getInstance("TLS");

    KeyStore ks = KeyStore.getInstance("JKS");
    ks.load(new FileInputStream(new File("svrks.jks")), "kspassword1".toCharArray());
    KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
    kmf.init(ks, "kspassword2".toCharArray());

    TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
    tmf.init(ks);

    sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
    SSLEngine sslEngine = sslContext.createSSLEngine();
    sslEngine.setUseClientMode(false);
    sslEngine.setNeedClientAuth(false);//one-way
    sslEngine.setEnabledProtocols(sslEngine.getSupportedProtocols());
    sslEngine.setEnabledCipherSuites(sslEngine.getSupportedCipherSuites());
    sslEngine.setEnableSessionCreation(true);

    ch.pipeline().addFirst("SSL", new SslHandler(sslEngine));
}
客户:

private void addSslHandlerOneWay(SocketChannel ch) throws Exception {
    SSLContext sslContext = SSLContext.getInstance("TLS");

    KeyStore ts = KeyStore.getInstance("JKS");
    ts.load(getInputStream("clits.jks"), "tspassword2".toCharArray());
    KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
    kmf.init(ts, "tspassword1".toCharArray());

    TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
    tmf.init(ts);

    sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
    SSLEngine sslEngine = sslContext.createSSLEngine();
    sslEngine.setUseClientMode(true);//client

    sslEngine.setEnabledProtocols(sslEngine.getSupportedProtocols());
    sslEngine.setEnabledCipherSuites(sslEngine.getSupportedCipherSuites());
    sslEngine.setEnableSessionCreation(true);

    ch.pipeline().addFirst("SSL", new SslHandler(sslEngine));
}
谢谢,伙计们

我认为单向身份验证意味着只有服务器持有证书

服务器需要使用证书对自身进行身份验证。为此,它需要证书和匹配的私钥。
客户端需要验证身份验证,即服务器发送的证书实际上是预期的证书。为此,它需要知道证书本身或颁发证书的CA,这与自签名证书的情况相同

您似乎期望的是,客户机不需要任何关于服务器证书或颁发者CA的先前知识。如果是这种情况,则客户机将只接受任何证书,包括来自服务器的更正证书和来自攻击者的伪造证书。如果事先不知道(即本地信任锚),服务器将无法区分正确证书和伪造证书

我认为单向身份验证意味着只有服务器持有证书

服务器需要使用证书对自身进行身份验证。为此,它需要证书和匹配的私钥。
客户端需要验证身份验证,即服务器发送的证书实际上是预期的证书。为此,它需要知道证书本身或颁发证书的CA,这与自签名证书的情况相同


您似乎期望的是,客户机不需要任何关于服务器证书或颁发者CA的先前知识。如果是这种情况,则客户机将只接受任何证书,包括来自服务器的更正证书和来自攻击者的伪造证书。如果事先不知道(即本地信任锚),服务器将无法区分正确证书和假证书。

除了Steffen的答案之外:大多数SSL/TLS客户端(包括所有web浏览器)都有一组他们默认信任的预审查CA,如Verisign GoDaddy等。如果您从其中一个CA获得并使用证书,则无需对客户端执行任何操作或更改。大多数“真正的”CA都是收费的,尽管通过购物,你每年只需几美元就可以找到基本的证书;LetsEncrypt不收费,现在被广泛信任——但在8u101之前在Java中不是默认的。除了Steffen的回答:大多数SSL/TLS客户端(包括所有web浏览器)都有一组他们默认信任的预审查CA,如Verisign GoDaddy等。如果您从其中一个CA获得并使用证书,则无需对客户端执行任何操作或更改。大多数“真正的”CA都是收费的,尽管通过购物,你每年只需几美元就可以找到基本的证书;LetsEncrypt不收费,现在广受信任——但在8u101之前,默认情况下在Java中是不收费的。