c# - 使用 ALPN 通过 TLS 连接
问题描述
我正在尝试使用 C# net core 2.1 类库连接到 Amazon IoT MQTT 代理。我的要求是我必须使用端口 443,这意味着根据亚马逊的文档,我必须使用支持 ALPN 的连接。
.Net Core 2.1 现在有支持这一点的方法,所以我尝试以下代码:
(注意:我可以使用端口 8883 而不是 443 尝试相同的代码,它可以正常连接并发送我的 MQTT 数据,所以我知道我的证书和端点地址是正确的。)
this.socket = new Socket(this.remoteIpAddress.GetAddressFamily(), SocketType.Stream, ProtocolType.Tcp);
this.socket.Connect(new IPEndPoint(this.remoteIpAddress, this.remotePort));
this.netStream = new NetworkStream(this.socket);
this.sslStream = new SslStream(this.netStream, false, this.userCertificateValidationCallback, this.userCertificateSelectionCallback);
X509CertificateCollection clientCertificates = null;
clientCertificates = new X509CertificateCollection(new X509Certificate[] { this.clientCert });
SslApplicationProtocol amzProtocol = new SslApplicationProtocol("x-amzn-mqtt-ca");
System.Threading.CancellationToken token = new System.Threading.CancellationToken();
SslClientAuthenticationOptions options = new SslClientAuthenticationOptions()
{
AllowRenegotiation = false,
TargetHost = this.remoteHostName,
ClientCertificates = clientCertificates,
EnabledSslProtocols = SslProtocols.Tls12,
CertificateRevocationCheckMode = X509RevocationMode.NoCheck,
ApplicationProtocols = new List<SslApplicationProtocol>() { amzProtocol },
LocalCertificateSelectionCallback = this.userCertificateSelectionCallback,
RemoteCertificateValidationCallback = this.userCertificateValidationCallback,
EncryptionPolicy = EncryptionPolicy.RequireEncryption
};
this.sslStream.AuthenticateAsClientAsync(options, token).Wait();
现在,据我了解,我应该看到(我正在使用 wireshark)添加到客户端 Hello 握手协议的扩展,类似于以下内容:
Extension: Application Layer Protocol Negotiation
Type: Application Layer Protocol Negotiation (0x0010)
Length: ##
ALPN Extension Length: ##
ALPN Protocol
ALPN string length: 14
ALPN Next Protocol: x-amzn-mqtt-ca
但是我没有得到那个扩展,并且端口 443 上的连接失败。
我在设置协议列表时遗漏了什么吗?我没有从中得到任何错误,但由于这是一个相当新的版本,因此没有很多参考资料可以寻找提示。
解决方案
好吧,看起来即使 Net CORE 2.1 已经添加了支持这一点的功能,它也不适用于 Windows 7。你必须使用 Windows 8.1 或更高版本。这没有在代码中的任何地方或 GitHub 上的示例中记录,但我从一个开发团队中发现,出于某种原因,他们决定让它“静默失败”,而不是抛出错误。
推荐阅读
- azure - Azure 技能日历 BoT 移交引发 websocket 异常
- mysql - MySQL:从字符串(或 varchar 字段)中提取第一个、第二个和第三个单词
- php - 尝试从命名空间“Symfony\WebpackEncoreBundle”加载类“WebpackEncoreBundle”。您是否忘记了另一个名称空间的“使用”语句?
- reactjs - 如何使用 Context API 更新组件提供者的状态
- powerbi - 隐藏另一个切片器的值的切片器
- c# - 如何使用 API 传输密码
- mongodb - 如何更新现有文档中的新数组
- powershell - 安装 dotnet core 问题
- python - 我想在列表中添加元素
- selenium-webdriver - 错误显示为“org.openqa.selenium.JavascriptException:javascript 错误:无法读取属性‘setAttribute’ of null”