android - url中使用IP时如何分配SNI?

标签 android ssl networking httpurlconnection sni

我有一台服务器 1.1.1.1,为多个主机 A.com 和 B.com 提供服务。 因此每个域都有自己的证书。

当我使用基于主机的网址时:

URL url = new URL("https://B.com/23o8PS");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.connect();
Certificate[] certificates = ((HttpsURLConnection) conn).getServerCertificates();
System.out.println(certificates.length + " " + certificates[0].toString());

我可以成功获取B.com的证书。但是如果我使用基于 IP 的 url(通过添加主机字段来指示主机),如下所示:

URL url = new URL("https://1.1.1.1/23o8PS");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Host", "B.com");
conn.connect();
Certificate[] certificates = ((HttpsURLConnection) conn).getServerCertificates();
System.out.println(certificates[0].toString());

我刚刚获得了 A.com 的证书,就好像它是从服务器作为默认证书返回的一样。看来SNI不能根据HttpURLConnection的HOST HEADER字段来设置。

有什么建议我可以如何处理这种情况吗?

最佳答案

Server Name Identification (SNI)是 TLS 握手的一部分。它在一开始就通过了,用于确定使用哪个服务器证书。该握手发生在发送任何 HTTP 请求之前 - 如果没有发生,HTTP 请求将以未加密的方式发送。

根据 RFC 4366:

3.1. Server Name Indication

TLS does not provide a mechanism for a client to tell a server the name of the server it is contacting. It may be desirable for clients to provide this information to facilitate secure connections to servers that host multiple 'virtual' servers at a single underlying network address.

...

Currently, the only server names supported are DNS hostnames; however, this does not imply any dependency of TLS on DNS, and other name types may be added in the future (by an RFC that updates this document). TLS MAY treat provided server names as opaque data and pass the names and types to the application.

"HostName" contains the fully qualified DNS hostname of the server, as understood by the client. The hostname is represented as a byte string using UTF-8 encoding [UTF8], without a trailing dot.

...

Literal IPv4 and IPv6 addresses are not permitted in "HostName".

您不能将 IP 地址与 SNI 一起使用。

这是有道理的 - SNI 的全部目的是在单个 IP 地址上支持多个虚拟主机。

另请参阅the Java JSSE documentation.

关于android - url中使用IP时如何分配SNI?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36716487/

相关文章:

java - 运行时错误: inflating class

java - 在伦敦地铁上进行网络检测

ios - Reachability.h bool 变量 connectionRequired——这是什么意思?

powershell - 如何使用 Powershell 验证保留 IP

android - 如何在android中为 GridView 实现onclickevent和ontouchevent

android - 适用于 Android 的 Olingo OData 2.0 - 对 javax.xml.stream.XMLInputFactory 的依赖

android - "mnt/sdcard"总是 Android 中的外部存储吗?

ruby - 如何确定应用程序使用的 TLS 版本?

ssl - 用 ssl 写名字

java - 相当频繁的 SSLPeerUnverifedException 与 PoolingClientConnectionManager