我在调用https webservice时遇到异常。
com.sun.xml.internal.ws.client.ClientTransportException: HTTP transport error: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names present.
我从Java代码调用php webservice。 CN(通用名称),即证书上的IP地址和我呼叫的IP地址是不同的。我已经在java的密钥库中添加了证书。 有人可以帮我解释为什么会这样吗?我哪里错了? CN是服务器IP地址。我因为防火墙问题而使用外部IP地址来呼叫该服务器。
答案 0 :(得分:3)
CN(通用名称),即证书上的IP不同,我正在呼叫的IP不同。
...
HTTP传输错误:javax.net.ssl.SSLHandshakeException:java.security.cert.CertificateException:不存在主题替代名称。
当公共名称(CN)中存在名称时,必须也出现在主题备用名称(SAN)中。您的证书格式不正确(可能还有其他问题)。见Baseline Requirements for the Issuance and Management of Publicly-Trusted Certificates,第9节(第9页和第10页):
9.2.2主题通用名称字段
证书字段:subject:commonName(OID 2.5.4.3)
必填/可选:已弃用(不鼓励,但未被禁止)
内容:如果存在,该字段必须包含单个IP地址或 完全限定的域名,是包含在其中的值之一 证书的subjectAltName扩展名(参见第9.2.1节)。
Bruno可能会引用RFC 6125的相关部分。
答案 1 :(得分:2)
在使用IP地址检查服务器的身份时,Java客户端通常严格遵守RFC 2818。这意味着IP地址必须位于主题备用名称条目中,而不是CN中。这是this question的详细信息。
修复证书以符合RFC 2818(即将IP地址放在IP地址SAN中)应修复java.security.cert.CertificateException: No subject alternative names present.
例外。
但是,由于您未使用证书中的IP地址调用服务器,因此您仍然会遇到问题。你有两个选择:
如果您可以找人修理证书,请为内部和外部IP地址添加两个SAN条目。这是迄今为止最好的选择(仅在该机器上设置名称的第二名,这可以更好地防止这类问题)。
在该连接使用的信任库中导入仅该证书并禁用主机名验证。 一般不要禁用主机名验证。禁用主机名验证的问题是任何有效证书都可以模拟任何其他可用于MITM攻击的证书。如果您信任的唯一证书是您要连接的唯一服务器(您可以通过为此目的设置单独的信任存储区来实现),则可以限制此风险。通常,对这些特殊情况进行编码会导致糟糕的遗留代码,有人可能会在以后不安全地接收和使用。因此,修复证书是更好的选择。