- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我可以使用 TLS 1.2 成功连接到我们的服务器。但是我们可以选择传入 SNI(在客户端问候消息中),这会将我们重定向到防火墙后面的另一台服务器。如何在 C# StreamSocket 或 SslStream 中指定 SNI(服务器名称指示符)?我在客户端找不到 C# 的任何示例。使用 Visual Studio 2017、C# 7.3、.NET 4.8.3752
这是我们的连接命令。
我们查看了 dotnetty、curl.net,可能还使用了 openSSL。
await socket.ConnectAsync(new HostName(serverAddress), serverPort.ToString(), SocketProtectionLevel.Tls12);
提前感谢您的任何想法或意见。
最佳答案
我们能够解决问题。我拼凑了几个部分示例,形成了在 StackOverflow 和其他来源上找到的 4 或 5 个结果。
基本上我无法使用 StreamSocket。我不得不使用 TcpClient 和 SslStream,我相信 StreamSocket 在内部使用它们(从我在许多搜索中发现的)。微软并没有让它变得容易,就像你可以使用 ObjectiveC 或 Java 一样。
首先您必须创建一个 TcpClient 实例:
_tcpClient = new TcpClient(_serverAddress, _serverPort);
然后创建一个 SslStream:
_socketStreamForReadSSL = new SslStream(
_tcpClient.GetStream()
, false
, new RemoteCertificateValidationCallback(ValidateServerCertificate));
请注意,在上面的代码片段中,我们设置了一个委托(delegate)来处理我们这边代码的远程服务器验证。这是因为 Microsoft 将验证 SNI 名称是否与主机地址匹配。为了覆盖此行为,他们慷慨地允许我们使用委托(delegate)(在答案中进一步查看)。
下一步是设置要在握手中使用的任何证书:
X509CertificateCollection certs = BuildX509CertCollection();
BuildX509CertCollection 是我编写的一种构建证书集合的方法,主要采用 Windows.Security.Cryptography.Certificates.Certificate 并使用 Certificate.GetCertificateBlob 生成的二进制文件将其转换为 X509Certificate。
现在下一步很关键,神奇的地方就在这里。我们将使用服务器对客户端进行身份验证。这是设置 SNI 的地方。我们还在此处设置协议(protocol) (TLS 1.2)。
_socketStreamForReadSSL.AuthenticateAsClient(sniAddress, certs, SslProtocols.Tls12, false);
如果您使用以下命令运行 WireShark,您可以跟踪通信,下面是我用来查看我的开发箱和服务器之间的 TLS 1.2 通信的示例命令,其中 XXX.XXX.XXX.XXX 是 ip你的服务器地址和你的目标
tls.record.version == "TLS 1.2" and ip.addr == XXX.XXX.XXX.XXX and ip.addr == XXX.XXX.XXX.XXX
部分 WireShark 结果展示了正在设置的 SNI anme
Internet Protocol Version 4, Src: XXX.XXX.XXX.XXX, Dst: XXX.XXX.XXX.XXX
Transmission Control Protocol, Src Port: <port number here>, Dst Port: <port number here>, Seq: 1, Ack: 1, Len: 196
Transport Layer Security
TLSv1.2 Record Layer: Handshake Protocol: Client Hello
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 191
Handshake Protocol: Client Hello
Handshake Type: Client Hello (1)
Length: 187
Version: TLS 1.2 (0x0303)
Random: blah...blah...blah
Session ID Length: 0
Cipher Suites Length: 42
Cipher Suites (21 suites)
Compression Methods Length: 1
Compression Methods (1 method)
Extensions Length: 104
Extension: server_name (len=45)
Type: server_name (0)
Length: 45
Server Name Indication extension
Server Name list length: 43
Server Name Type: host_name (0)
Server Name length: 40
Server Name: <sni name shows up here>
如前所述,远程证书验证委托(delegate)。这在验证服务器证书和 SNI 名称时由 SslStream 调用。在我们的实例中,我们确保服务器地址的结尾和 SNI 名称的结尾与通用名称 (CN) 匹配,但您可以执行您认为合适的任何验证。通过返回 true,失败返回 false,如果为 false,AuthenticateAsClient 将抛出异常。
private bool ValidateServerCertificate(
object sender
, X509Certificate certificate
, X509Chain chain
, SslPolicyErrors sslPolicyErrors)
{
// Do not allow this client to communicate with unauthenticated servers.
bool result = false;
switch (sslPolicyErrors)
{
case SslPolicyErrors.None:
result = true;
break;
case SslPolicyErrors.RemoteCertificateNameMismatch:
X509Certificate2 cert = new X509Certificate2(certificate);
string cn = cert.GetNameInfo(X509NameType.SimpleName, false);
string cleanName = cn.Substring(cn.LastIndexOf('*') + 1);
string[] addresses = { _serverAddress, _serverSNIName };
// if the ending of the sni and servername do match the common name of the cert, fail
result = addresses.Where(item => item.EndsWith(cleanName)).Count() == addresses.Count();
break;
default:
result = false;
break;
}
return result;
}
关于c# - 在客户端为 StreamSocket 或 SslStream 设置 SNI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57399520/
DataReader.LoadAsync 不检测关闭的套接字(使用 InputStreamOptions::Partial) 我正在通过 TCP 连接向服务器发送数据并读取响应,但之后一切正常。但是在
我有一个 StreamSocket,我在关闭 UWP 应用程序期间将其丢弃。我的具有 Socket 连接的客户端仍然认为连接是事件的,即使应用程序已经关闭。 只有在重新启动套接字时,我的客户端才会给出
我正在开发一个 C#、UWP 10 解决方案,它使用快速、连续的读/写循环与网络设备通信。 API 提供的 StreamSocket 似乎工作得很好,直到我意识到存在内存泄漏:累积了 Task。在堆中
我正在使用 StreamSocketListener 在 Windows Phone 8(充当服务器)上接收由 HTTP POST 客户端发送的数据。我可以接收数据,但是当读取所有数据时,DataRe
所以我已经收到这个异常大约一个星期了,我终于设法将它变成一个易于阅读的代码片段。 作为背景,我正在为 Windows RT 编写一个应用程序,我正在尝试使用基本套接字。 为了测试,我创建了一个本地套接
我有一台运行 MPD(音乐播放器守护程序)的服务器,它通过套接字进行通信。现在我正在尝试在 Windows 商店应用程序中实现 MPD 协议(protocol)。基本上我发送一个命令并收到一个列表,该
我正在研究 WinRT(Windows8 Release Preview)。我有一个 Web 应用程序(实际上是一个更简单的 XMPP 客户端)。 我主要使用 StreamSocket 类来连接 Ja
我有一个 WinRT 应用程序,它使用 StreamSocket 和 DataWriter 执行上传。它跟踪上传所花费的时间,然后计算吞吐量。 我遇到的问题是我获得的吞吐量远高于 Wireshark
我正在尝试在 C# 中为 UWP 实现 XMPP 客户端,为了实现这一点,我使用 StreamSocket 进行 TCP 连接。 问题是对于握手和SASL auth,我需要服务器从客户端进行一系列“写
我正在尝试通过 StreamSocket 发送 HTTP 请求,但响应被 chop 为 “failedWinRTError:对象已关闭。” 这是我的代码: var count, hostName,
我的 Windows Phone 8 应用程序中有以下代码。 //connection code, done during app start socket = new StreamSocket();
在 Windows Phone 8.1 应用程序中,我必须按如下方式创建套接字。我如何更改它,以便它在我可以指定的时间段后超时? _socket = new StreamSocket(); await
我发布这个是因为我已经浪费了一天的时间来搜索和编程一个即使在 Metro 中也应该很容易设置的东西。 我正在寻找一个 C# StreamSocket 示例,它可以连接到套接字,从套接字读取数据(我不确
我尝试将已连接的 StreamSocket 附加到 SecureStreamSocket: class MyConnection : public TCPServerConnection { pr
我有以下 c#/WinRT 代码来接收来自 IMAP 命令的响应 DataReader reader = new DataReader(sock.InputStream); reader.InputS
使用 Windows StreamSocket 类 (TCP) 处理断开连接和重新连接事件的正确方法是什么? 我有一个问题,在断开连接事件后调用 async_connect 时调用“无效操作,在意外时
我有一个正在为 Windows 8/WinRT 编写的应用程序,它使用 StreamSocket API 与服务器建立流式连接。也就是说,服务器向客户端流式传输数据,有时带有元标记,并且可以随时断开连
我可以使用 TLS 1.2 成功连接到我们的服务器。但是我们可以选择传入 SNI(在客户端问候消息中),这会将我们重定向到防火墙后面的另一台服务器。如何在 C# StreamSocket 或 SslS
这是最小的可能场景,我能够准备: 此代码连接到 imap.gmail.com 读取初始服务器问候语(使用 Read 方法) 发送 NOOP 命令(NO 操作) 读取 NOOP 命令响应(再次使用 Re
我正在创建一个 Win 8 商店应用程序,我在其中使用 StreamSocket 连接到一个用 Java 编写的服务器。当我在调试中运行应用程序时,在 StreamSocket.ConnectAsyn
我是一名优秀的程序员,十分优秀!