【问题标题】:How to verify server (peer) name after x509 SSL/TLS handshake using SSLEngine?如何使用 SSLEngine 在 x509 SSL/TLS 握手后验证服务器(对等)名称?
【发布时间】:2012-07-13 10:29:47
【问题描述】:

我正在使用 SSLEngineNIO 进行非阻塞 TLS 通信。

引擎工作正常,能够验证CA信任,服务器证书的有效期。

但我缺少的是证书使用者名称与我要连接的服务器名称匹配的验证。

考虑到subject alternative names 等所有 SSL 扩展,实现它的最佳方式是什么?

我尝试简单地检查主题名称,但即使使用 google.nl 也不起作用,证书中的主题是 google.com,而 google.nl 只能在替代名称扩展中找到。

【问题讨论】:

    标签: java jsse sslengine


    【解决方案1】:

    又要回答我自己的问题了……

    到目前为止,我能够做到这一点。它仅限于 Sun JSSE 实现。不确定这是否是一个完整的解决方案。

    void checkServerName(String serverName, SSLSession session) throws IOException {
        String name;
        boolean matches = false;
        X509CertImpl cert = (X509CertImpl)session.getPeerCertificates()[0];
        SubjectAlternativeNameExtension altNames = cert.getSubjectAlternativeNameExtension();
        if (altNames != null) {
            GeneralNames names = (GeneralNames) altNames.get(SubjectAlternativeNameExtension.SUBJECT_NAME);
            for (GeneralName genName : names.names()) {
                switch (genName.getType()) {
                    case GeneralNameInterface.NAME_DNS:
                        name = ((DNSName)genName.getName()).getName();
                        break;
                    case GeneralNameInterface.NAME_IP:
                        name = ((IPAddressName)genName.getName()).getName();
                        break;
                    case GeneralNameInterface.NAME_RFC822:
                        name = ((RFC822Name)genName.getName()).getName();
                        break;
                    case GeneralNameInterface.NAME_ANY:
                        DerValue derValue = new DerValue(((OtherName)genName.getName()).getNameValue()); 
                        name = derValue.getData().getUTF8String();
                        break;
                    default:
                        continue;
                }
                if (name.startsWith("*"))
                    matches |= serverName.endsWith(name.substring(1).toLowerCase());
                else
                    matches |= serverName.equals(name.toLowerCase());
                if (matches)
                    break;
            }
        }
        name = ((X500Name)cert.getSubjectDN()).getCommonName();
        if (!matches)
            matches = serverName.equals(name.toLowerCase());
        if (!matches)
            throw new SSLPeerUnverifiedException("server name mismatch, certificate issued to: " + name);
    }
    

    【讨论】:

      猜你喜欢
      • 2020-10-11
      • 1970-01-01
      • 1970-01-01
      • 2021-08-21
      • 2019-04-12
      • 2020-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多