2017-10-05 59 views
0


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

这是我的问题:
有没有什么办法可以让我不需要向我的客户端添加信任库,我只将密钥库添加到我的服务器上,它仍然可以正常工作?我认为单向认证意味着只有服务器持有证书?使用Netty进行单向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)); 
} 

谢谢,伙计们。

+0

除了Steffen的回答:大多数SSL/TLS客户端(包括所有Web浏览器)都有一组默认信任的预先验证的CA,例如Verisign GoDaddy等。如果您获得并使用来自其中一个CA则无需对客户进行任何操作或更改。大多数“真正的”CA都会收取费用,但通过购物可以每年只能获得几美元的基本证书; LetsEncrypt什么也不收费,现在已经被广泛信任 - 但直到8u101之前,Java中才会默认使用它。 –

回答

2

我以为单向认证意味着只有服务器持有证书吗?

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

您似乎期望的是客户端不需要任何有关服务器证书或发行者CA的任何先前知识。如果是这种情况,那么客户端就会接受任何证书,这两个都会纠正服务器中的证书,并且还会从攻击者那里伪造证书。在没有先前的知识(即本地信任锚)的情况下,服务器无法区分正确证书和假证书。