0

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

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

但我缺少的是证书主题名称与我连接的服务器名称匹配的验证。

考虑到主题替代名称等所有 SSL 扩展,实现它的最佳方法是什么?

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

4

1 回答 1

0

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

到目前为止,我能够做到这一点。它仅限于 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);
}
于 2012-07-16T12:34:45.777 回答