Xamarin 中使用 TLS 1.2 的 Https [英] Https with TLS 1.2 in Xamarin

查看:36
本文介绍了Xamarin 中使用 TLS 1.2 的 Https的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Xamarin 中使用 HttpClient 向带有 TLS 1.2 的 https 请求,但出现如下错误;

I'm using HttpClient in Xamarin to request to https with TLS 1.2 and I got the error as below;

System.AggregateException: One or more errors occurred ---> System.Net.WebException: Error writing headers ---> System.IO.IOException: The authentication or decryption has failed. ---> Mono.Security.Protocol.Tls.TlsException: The authentication or decryption has failed.
  at Mono.Security.Protocol.Tls.RecordProtocol.ProcessAlert (AlertLevel alertLevel, AlertDescription alertDesc) [0x00013] in ///Library/Frameworks/Xamarin.iOS.framework/Versions/8.9.1.3/src/mono/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs:574 
  at Mono.Security.Protocol.Tls.RecordProtocol.InternalReceiveRecordCallback (IAsyncResult asyncResult) [0x000d0] in ///Library/Frameworks/Xamarin.iOS.framework/Versions/8.9.1.3/src/mono/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs:376 
  --- End of inner exception stack trace ---
  at Mono.Security.Protocol.Tls.SslClientStream.EndNegotiateHandshake (IAsyncResult result) [0x00035] in ///Library/Frameworks/Xamarin.iOS.framework/Versions/8.9.1.3/src/mono/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslClientStream.cs:425 
  at Mono.Security.Protocol.Tls.SslStreamBase.AsyncHandshakeCallback (IAsyncResult asyncResult) [0x0000c] in ///Library/Frameworks/Xamarin.iOS.framework/Versions/8.9.1.3/src/mono/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslStreamBase.cs:99 
  --- End of inner exception stack trace ---
  at System.Net.HttpWebRequest.EndGetResponse (IAsyncResult asyncResult) [0x0005e] in ///Library/Frameworks/Xamarin.iOS.framework/Versions/8.9.1.3/src/mono/mcs/class/System/System.Net/HttpWebRequest.cs:969 
  at System.Threading.Tasks.TaskFactory`1[System.Net.WebResponse].InnerInvoke (System.Threading.Tasks.TaskCompletionSource`1 tcs, System.Func`2 endMethod, IAsyncResult l) [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Threading.Tasks/TaskFactory_T.cs:473 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000b] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Runtime.ExceptionServices/ExceptionDispatchInfo.cs:62 
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[System.Net.WebResponse].GetResult () [0x00034] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Runtime.CompilerServices/ConfiguredTaskAwaitable_T.cs:62 
  at System.Net.Http.HttpClientHandler+<SendAsync>c__async0.MoveNext () [0x002d0] in /Developer/MonoTouch/Source/mono/mcs/class/System.Net.Http/System.Net.Http/HttpClientHandler.cs:338 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000b] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Runtime.ExceptionServices/ExceptionDispatchInfo.cs:62 
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[System.Net.Http.HttpResponseMessage].GetResult () [0x00034] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Runtime.CompilerServices/ConfiguredTaskAwaitable_T.cs:62 
  at System.Net.Http.HttpClient+<SendAsyncWorker>c__async0.MoveNext () [0x000a9] in /Developer/MonoTouch/Source/mono/mcs/class/System.Net.Http/System.Net.Http/HttpClient.cs:273 
  --- End of inner exception stack trace ---
  at System.Threading.Tasks.Task.Wait (Int32 millisecondsTimeout, CancellationToken cancellationToken) [0x00049] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Threading.Tasks/Task.cs:709 
  at System.Threading.Tasks.Task.Wait () [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Threading.Tasks/Task.cs:679 
  at System.Threading.Tasks.Task`1[System.Net.Http.HttpResponseMessage].get_Result () [0x0000b] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Threading.Tasks/Task_T.cs:48 
  at Cucumber.ViewModels.LoginViewModel+<ExecuteLoginCommand>c__async0.MoveNext () [0x00144] in /Users/bachpx1/FSBProjects/FsoftInternalNews/cucumber/xamarin_form/Cucumber/Cucumber.Shared/ViewModels/LoginViewModel.cs:94 
 --> (Inner exception 0) System.Net.WebException: Error writing headers ---> System.IO.IOException: The authentication or decryption has failed. ---> Mono.Security.Protocol.Tls.TlsException: The authentication or decryption has failed.
  at Mono.Security.Protocol.Tls.RecordProtocol.ProcessAlert (AlertLevel alertLevel, AlertDescription alertDesc) [0x00013] in ///Library/Frameworks/Xamarin.iOS.framework/Versions/8.9.1.3/src/mono/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs:574 
  at Mono.Security.Protocol.Tls.RecordProtocol.InternalReceiveRecordCallback (IAsyncResult asyncResult) [0x000d0] in ///Library/Frameworks/Xamarin.iOS.framework/Versions/8.9.1.3/src/mono/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs:376 
  --- End of inner exception stack trace ---
  at Mono.Security.Protocol.Tls.SslClientStream.EndNegotiateHandshake (IAsyncResult result) [0x00035] in ///Library/Frameworks/Xamarin.iOS.framework/Versions/8.9.1.3/src/mono/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslClientStream.cs:425 
  at Mono.Security.Protocol.Tls.SslStreamBase.AsyncHandshakeCallback (IAsyncResult asyncResult) [0x0000c] in ///Library/Frameworks/Xamarin.iOS.framework/Versions/8.9.1.3/src/mono/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslStreamBase.cs:99 
  --- End of inner exception stack trace ---
  at System.Net.HttpWebRequest.EndGetResponse (IAsyncResult asyncResult) [0x0005e] in ///Library/Frameworks/Xamarin.iOS.framework/Versions/8.9.1.3/src/mono/mcs/class/System/System.Net/HttpWebRequest.cs:969 
  at System.Threading.Tasks.TaskFactory`1[System.Net.WebResponse].InnerInvoke (System.Threading.Tasks.TaskCompletionSource`1 tcs, System.Func`2 endMethod, IAsyncResult l) [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Threading.Tasks/TaskFactory_T.cs:473 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000b] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Runtime.ExceptionServices/ExceptionDispatchInfo.cs:62 
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[System.Net.WebResponse].GetResult () [0x00034] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Runtime.CompilerServices/ConfiguredTaskAwaitable_T.cs:62 
  at System.Net.Http.HttpClientHandler+<SendAsync>c__async0.MoveNext () [0x002d0] in /Developer/MonoTouch/Source/mono/mcs/class/System.Net.Http/System.Net.Http/HttpClientHandler.cs:338 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000b] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Runtime.ExceptionServices/ExceptionDispatchInfo.cs:62 
  at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[System.Net.Http.HttpResponseMessage].GetResult () [0x00034] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Runtime.CompilerServices/ConfiguredTaskAwaitable_T.cs:62 
  at System.Net.Http.HttpClient+<SendAsyncWorker>c__async0.MoveNext () [0x000a9] in /Developer/MonoTouch/Source/mono/mcs/class/System.Net.Http/System.Net.Http/HttpClient.cs:273 

有谁知道如何解决这个问题.我听说 Xamarin 是 Mono 2.0 中的 TLS 错误.非常感谢

推荐答案

TLS 是 尚未在 Mono 中完全实现.这意味着在 Windows 上运行 .NET 应用程序时,您的 HTTPS 请求可能会失败.

TLS is not yet fully implemented in Mono. That means your HTTPS requests may fail where they would not when running your .NET app on Windows.

由于您使用的是 Xamarin,您可以使用 ModernHttpClient,它是原生 iOS/Android 的包装器网络库.

Since you are using Xamarin, you can use ModernHttpClient which is a wrapper around the native iOS / Android networking libraries.

Android、Mac 和 iOS 用户可以获得用于 HTTP 工作负载的最新 TLS使用 ModernHttpClient.Mac/iOS 用户可以使用内置的CFNetworkHandler 也是如此.

Android, Mac and iOS users can get the latest TLS for HTTP workloads using ModernHttpClient. Mac/iOS users can use the built-in CFNetworkHandler as well.

Linux/Mac 部署

如果您要在 Linux/Mac(不带 Xamarin)上部署 Mono,您需要找到一种解决方法来解决缺少 TLS 支持的问题.

Linux/Mac Deployment

If you are deploying Mono on Linux/Mac (without Xamarin), you'll need to find a workaround for the lack of TLS support.

想到了两种可能的解决方法:

There are 2 possible workarounds that come to mind:

尝试使用 juhovh/AaltoTLS,这是完全使用编写的 SSL/TLS 网络协议的实现C# 和 .NET 的标准加密库(如果相关).它将负责 TLS 解密/加密,并且不会使用内置的缺少 Mono 实现.

Try using juhovh/AaltoTLS, which is an implementation of the SSL/TLS network protocol written completely using C# and standard cryptographic libraries of .NET where relevant. It will take care of the TLS decryption/encryption and won't use the built-in lacking Mono implementation.

构建一个 TLS 代理,它将为您完成 TLS 的繁重工作——您将其配置为 Mono 中 HTTP 请求的 HTTP 代理,它将接收它们,并查询目标服务器通过 HTTPS,处理 Mono 应用程序的加密和解密.

Build a TLS Proxy that will do the TLS heavy-lifting for you -- you'll configure it as an HTTP proxy for your HTTP requests in Mono, it will receive them, and query the target server via HTTPS, handling the encryption and decryption for the Mono app.

工作流程:

Mono App -> HttpClient 通过 TLS Proxy 发送 HTTP 请求 -> TLS Proxy 将 HTTP 请求转换为 HTTPS 并发送到目标服务器 -> TLS Proxy 接收响应 -> TLS Proxy 以 HTTP 格式将响应发送回 HttpClient

Mono App -> HttpClient sends HTTP request via TLS Proxy -> TLS Proxy converts HTTP request to HTTPS and sends it to target server -> TLS Proxy receives response -> TLS Proxy sends back response to HttpClient in HTTP format

Node.js 中使用 nodejitsu/node-http-proxy 解决 TLS 代理的示例代码:

Example code in Node.js for the TLS Proxy workaround using nodejitsu/node-http-proxy:

// Modules
var http = require('http');
var httpProxy = require('http-proxy');

// Proxy server options
var options = {secure: true}; // Validate remote SSL certificates

// Create a proxy server with custom application logic
var proxy = httpProxy.createProxyServer(options);

// Handle errors gracefully
proxy.on('error', function(e) {
    // Log to console
    console.log(e);
});

// Create server and define custom logic
var server = http.createServer(function(req, res) {
    // URL provided?
    if (req.url) { 
        // Convert to HTTPS
        req.url = req.url.replace('http://', 'https://');
    }

    // Get remote host from headers (and force HTTPS)
    var target = 'https://' + req.headers.host;

    // Proxy the request (target is the server to pass the request on to)
    proxy.web(req, res, { target: target });
});

// Proxy port
var port = 8080;

// Start listening for requests from clients
server.listen(port);

// Log the port number
console.log('proxy.port: ' + port);

这篇关于Xamarin 中使用 TLS 1.2 的 Https的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆