【问题标题】:Server Name Indication from C#来自 C# 的服务器名称指示
【发布时间】:2013-11-14 06:40:17
【问题描述】:

据我所知,.NET 似乎有一个很大的限制,因为无法使用 C# 和 .NET 建立使用服务器名称指示 (SNI) 的 TLS 连接。我是否遗漏了什么或者我的理解是否正确?

有人知道我是否以及如何使用 OpenSSL.NET、libcurl.NET 或其他一些 3rd 方 .NET 库建立 SNI 连接?一些示例代码将不胜感激。

【问题讨论】:

  • 我们的 SecureBlackbox 完全支持客户端和服务器 TLS 组件中的 SNI
  • 谢谢,我去看看。
  • SNI 是 TLS 扩展,而不是 SSL,所以第一步是选择正确的协议。但是,是的,.NET 从 4.5 开始不支持 SNI,这真是太可惜了。 connect.microsoft.com/VisualStudio/feedback/details/729925/…
  • @Bruno 谢谢我更新了问题以说明正确的协议。如果 IETF 将他们的版本称为 SSL v4 会更容易;-)
  • @EugeneMayevski'EldoSCorp 是否有关于如何将TElHTTPSClient 类与 SNI 一起使用的文档(最好是示例代码)? This page 仅列出班级成员,但不提供进一步指导。也没有安装示例项目来展示如何使用 HTTPS。

标签: c# .net ssl libcurl sni


【解决方案1】:

在我的 .Net 4.5 项目中,使用 SNI 的服务器出现以下故障:

var url = "https://www.somesite.com";
System.Net.WebClient client = new System.Net.WebClient();
client.Encoding = Encoding.UTF8;
var data = client.DownloadString(url);

但如果通过前缀明确指定 TLS1.2,它会起作用:

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

同样适用于 webrequest:

WebRequest request = WebRequest.Create("https://www.somesite.com");

和 HttpRequestMessage:

var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "https://www.google.com");

他们都需要明确设置为 TLS 1.2 的协议才能与 SNI 服务器一起工作(这可能在较新的 .Net 版本中有所改变)

【讨论】:

【解决方案2】:

这是一篇相当老的帖子,但这个答案仍然可能对某些人有所帮助,至少它花了我几天的时间。

.NET Framework 默认支持服务器名称指示。 (在 4.5.1 上测试过,但我想至少对于 .NET 4.5+ 来说是一样的)

一个简短的例子:

HttpResponseMessage response;
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "https://www.google.com");

var handler = new HttpClientHandler
{
    CookieContainer = new CookieContainer()
};
using (var client = new HttpClient(handler))
{
    response = client.SendAsync(httpRequestMessage).Result;
}

这是在 C# 中创建 GET 请求的一种非常标准的方法。你会看到,在我的例子中,这个例子是使用带有 SNI 的 TLS 1.2 运行的。如果您使用 Wireshark 查看实际发送的包,您将看到一个 Client Hello,其中 Server Name Indication 设置为 www.google.com。

我们遇到的一个问题:SNI 标记是由 .NET Framework(或 Windows 的 Schannel,不确定)基于 HttpRequestMessage 的构造函数中传递的 URL 设置的。如果您知道基于某个 URL(例如 https://www.google.com)初始化请求,然后您切换 RequestUri OR Host 标头, SNI 标签仍将基于原始 url URL 创建。例如,如果您通过请求并将所有原始标头重新映射到新创建的请求,则可能会出现这种情况。

【讨论】:

  • 恐怕我无法重现您在上一段中提到的行为(这很不幸,因为我希望将其用作修改 SNI 标签的一种骇人听闻的方式)。我有posted this as a follow-up question
猜你喜欢
  • 2017-05-23
  • 1970-01-01
  • 2012-09-03
  • 1970-01-01
  • 2013-06-16
  • 1970-01-01
  • 2013-11-03
  • 2011-06-08
  • 2011-07-04
相关资源
最近更新 更多