SSL 证书服务器名称如何解析/我可以使用 keytool 添加替代名称吗? [英] How are SSL certificate server names resolved/Can I add alternative names using keytool?

查看:23
本文介绍了SSL 证书服务器名称如何解析/我可以使用 keytool 添加替代名称吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

These may be phrased as separate questions for clarity, but they are all related to the same issue.

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

How are SSL certificate server names resolved?

为什么浏览器好像要用到证书的CN字段,而Java的机制好像只看主题替代名称"?

Why do browsers seem to use the CN field of the certificate, but Java's mechanism seem to only look at "subject alternative names" only?

是否可以使用 keytool 向 SSL 证书添加替代名称?如果没有,使用 openSSL 是不是一个不错的选择??

Is it possible to add alternative names to a SSL certificate using keytool? If not, is using openSSL instead a good option??

一点背景知识:我需要让一个主服务器与使用 HTTPS 的多个服务器进行通信.显然,我们不想为每个服务器购买 SSL 证书(可能有很多),所以我想使用自签名证书(我一直在使用 keytool 生成它们).在我将证书添加为操作系统中受信任后,浏览器(IE 和 Chrome)很乐意接受该连接作为受信任的连接.但是,即使在将证书添加到 Java 的 cacerts 之后,Java 仍然不会接受该连接为可信连接并抛出以下异常:

Just a little background: I need to get a main server to communicate with several servers using HTTPS. Obviously, we don't want to buy SSL certificates for every server (there could be many), so I want to use self-signed certificates (I have been using keytool to generate them). After I add the certificates as trusted in the OS, the browsers (IE and Chrome) happily accept the connection as trusted. However, even after adding the certificates to Java's cacerts, Java still won't accept the connection as trusted and throws the following Exception:

Caused by: java.security.cert.CertificateException: 没有主题替代名称展示在 sun.security.util.HostnameChecker.matchIP(HostnameChecker.java:142)在 sun.security.util.HostnameChecker.match(HostnameChecker.java:75)在 com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:264)在 com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:250)在 com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(客户端tHandshaker.java:1185)……还有 14 个

Caused by: java.security.cert.CertificateException: No subject alternative names present at sun.security.util.HostnameChecker.matchIP(HostnameChecker.java:142) at sun.security.util.HostnameChecker.match(HostnameChecker.java:75) at 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 more

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

I found that I can make Java trust the certificate implementing my own HostNameVerifier, which I copied from here: com.sun.jbi.internal.security.https.DefaultHostnameVerifier just to test (by the way, the hostname passed as an argument to the HostnameVerifier is correct, so I think it should have been accepted).

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

I have been using the certificate field CN as the hostname (usually the IP address).

有人能告诉我我做错了什么并指出正确的方向吗?

Can anybody please tell me if I am doing something wrong and point me in the right direction?

推荐答案

RFC 6125,它是最近的并且将实践推广到所有协议,并替换了 RFC 2818,特定于 HTTPS.(我什至不确定 Java 7 是否使用 RFC 6125,这对于此来说可能太新了.)

How host name verification should be done is defined in RFC 6125, which is quite recent and generalises the practice to all protocols, and replaces RFC 2818, which was specific to HTTPS. (I'm not even sure Java 7 uses RFC 6125, which might be too recent for this.)

来自 RFC 2818(第 3.1 节):

如果存在 dNSName 类型的 subjectAltName 扩展,则必须用作身份.否则,(最具体的)通用名称必须使用证书主题字段中的字段.虽然通用名称的使用是现有的做法,它已被弃用,并且鼓励证书颁发机构改用 dNSName.

If a subjectAltName extension of type dNSName is present, that MUST be used as the identity. Otherwise, the (most specific) Common Name field in the Subject field of the certificate MUST be used. Although the use of the Common Name is existing practice, it is deprecated and Certification Authorities are encouraged to use the dNSName instead.

[...]

在某些情况下,URI 被指定为 IP 地址而不是主机名.在这种情况下,必须存在 iPAddress subjectAltName在证书中,并且必须与 URI 中的 IP 完全匹配.

In some cases, the URI is specified as an IP address rather than a hostname. In this case, the iPAddress subjectAltName must be present in the certificate and must exactly match the IP in the URI.

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

Essentially, the specific problem you have comes from the fact that you're using IP addresses in your CN and not a host name. Some browsers might work because not all tools follow this specification strictly, in particular because "most specific" in RFC 2818 isn't clearly defined (see discussions in RFC 6215).

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

If you're using keytool, as of Java 7, keytool has an option to include a Subject Alternative Name (see the table in the documentation for -ext): you could use -ext san=dns:www.example.com or -ext san=ip:10.0.0.1.

您可以通过更改 openssl.cnf 在 OpenSSL 中请求 SAN(如果您不想编辑全局配置,它会选择当前目录中的副本,据我所知,或者您可以使用 OPENSSL_CONF 环境变量选择一个明确的位置).

You can request a SAN in OpenSSL by changing openssl.cnf (it will pick the copy in the current directory if you don't want to edit the global configuration, as far as I remember, or you can choose an explicit location using the OPENSSL_CONF environment variable).

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

Set the following options (find the appropriate sections within brackets first):

[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

There's also a nice trick to use an environment variable for this (rather in than fixing it in a configuration file) here: http://www.crsr.net/Notes/SSL.html

这篇关于SSL 证书服务器名称如何解析/我可以使用 keytool 添加替代名称吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆