在Java中验证SSL证书的通用名称

时间:2010-12-23 03:43:44

标签: java sockets ssl-certificate

我正打开一个安全的SSL套接字到我服务器上的端口12345。我现在正在使用自签名证书。我将证书安装到我的服务器密钥库和客户端信任库中;好吧,等等等等。

我正在建立这个例子:http://www.exampledepot.com/egs/javax.net.ssl/Client.html

客户端正确验证服务器是否具有签名证书。客户端似乎没有验证所提供的证书CN(公共名称)是否与我正在连接的服务器的主机名匹配。显然,如果没有要求它与请求的域匹配,那么获得签名证书并不困难。

当我安装我的证书(使用keytool --import)时,我是否将其安装为根级证书?我是否需要使用第一个证书的主键签署第二个证书?为什么TrustManager不验证通用名称?

我希望这是有道理的,我并没有过度思考这一切。

谢谢!

更新:似乎Java SSL可能要求手动验证证书? (http://www.java2s.com/Open-Source/Java-Document/Net/Apache-common-HttpClient/org/apache/commons/httpclient/contrib/ssl/StrictSSLProtocolSocketFactory.java.htm)这真的是真的吗?我本以为默认是安全的,任何更少的默认都需要显式覆盖。我很惊讶。有人可以证实吗?

2 个答案:

答案 0 :(得分:11)

验证主机名取决于应用程序。它通过HttpsURLConnectionHostnameVerifier类在HTTPS的情况下内置于Java中。如果您直接使用SSLSocket,则由您决定,通常是HandshakeCompletedListener.

答案 1 :(得分:1)

你可能有这样的代码吗?这将忽略您提到的主机名不匹配。

HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier(){
    public boolean verify(String string,SSLSession ssls) {
        return true;
    }
});

否则,正如this link中的一条评论所说,您将获得例外HTTPS hostname wrong: should be...