首页 文章

如何解析SSL证书服务器名称/我可以使用keytool添加备用名称吗?

提问于
浏览
65

为清楚起见,这些可能被表述为单独的问题,但它们都与同一问题有关 .

SSL证书服务器名称是如何解析的?

为什么浏览器似乎使用证书的CN字段,但Java的机制似乎只关注“主题替代名称”?

是否可以使用keytool为SSL证书添加备用名称?如果没有,是使用openSSL而不是一个好的选择?

Just a little background: 我需要让主服务器使用HTTPS与多个服务器通信 . 显然,我们没有cacerts,Java仍然不接受连接为可信任并抛出以下异常:

引起:java.security.cert.CertificateException:在sun.security.util.HostnameChecker.match(HostnameChecker.java:75)sun.security.util.HostnameChecker.matchIP(HostnameChecker.java:142)上没有主题备用名称 . )com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkIdentity(X509T rustManagerImpl.java:264)at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:250)at com .sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Clien tHandshaker.java:1185)... 14更多

我发现我可以让Java信任实现我自己的HostNameVerifier的证书,我从这里复制了:com.sun.jbi.internal.security.https.DefaultHostnameVerifier只是为了测试(顺便说一下,作为HostnameVerifier的参数传递的主机名是正确的,所以我认为应该已经接受了) .

我一直使用证书字段CN作为主机名(通常是IP地址) .

任何人都可以告诉我,如果我做错了什么,并指出我正确的方向?

1 回答

  • 89

    如何进行主机名验证在RFC 6125中定义,这是最新的,并将实践概括为所有协议,并替换了特定于HTTPS的RFC 2818 . (我甚至不确定Java 7是否使用RFC 6125,这可能是最新的 . )

    来自RFC 2818 (Section 3.1)

    如果存在类型为dNSName的subjectAltName扩展名,则必须将其用作标识 . 否则,必须使用证书的Subject字段中的(最具体的)Common Name字段 . 尽管使用Common Name是现有做法,但不推荐使用它,并且鼓励证书颁发机构使用dNSName . [...]在某些情况下,URI被指定为IP地址而不是主机名 . 在这种情况下,iPAddress subjectAltName必须存在于证书中,并且必须与URI中的IP完全匹配 .

    基本上,您遇到的具体问题来自于您在CN中使用IP地址而不是主机名 . 有些浏览器可能会工作,因为并非所有工具都严格遵循此规范,特别是因为RFC 2818中的“最具体”工具没有明确定义(请参阅RFC 6215中的讨论) .

    如果您正在使用 keytool ,则as of Java 7, keytool可以选择包含主题备用名称(请参阅 -ext 文档中的表格):您可以使用 -ext san=dns:www.example.com-ext san=ip:10.0.0.1 .

    EDIT:

    您可以通过更改_2796100来在OpenSSL中请求SAN(如果您不想编辑全局配置,它将在当前目录中选择副本,或者您可以使用 OPENSSL_CONF 环境变量选择显式位置) .

    设置以下选项(首先在括号内找到相应的部分):

    [req]
    req_extensions = v3_req
    
    [ v3_req ]
    subjectAltName=IP:10.0.0.1
    # or subjectAltName=DNS:www.example.com
    

    这里还有一个很好的技巧来使用环境变量(而不是在配置文件中修复它):http://www.crsr.net/Notes/SSL.html

相关问题