Xamarin 中的 SSL 握手失败

SSL handshake fails in Xamarin

我正在尝试访问我的 RESTful API 以从 MySQL 数据库中检索数据。在我的 C# WPF 项目中,一切都已设置并完美运行。但是当在 Xamarin Forms(为 Android 构建)中使用完全相同的代码时,我无法与我的服务器成功进行 SSL 握手。

服务器详细信息

我正在使用 Flurl.Http(使用 HttpClient)建立连接,但在 jsonReader.Wait():

上出现异常
var jsonReader = "https://example.com/my_api/api.php/records/my_table?order=id,desc&size=10"
            .WithHeader("Accept", "application/json")
            .WithBasicAuth("username", "password")
            .GetJsonAsync<JsonRootObject>();
            // Wait for completion.
            jsonReader.Wait();


这是我的 AggregateException:

System.AggregateException: One or more errors occurred. (Call failed. An error occurred while sending the request
GET https://example.com/my_api/api.php/records/my_table?order=id,desc&size=10) ---> Flurl.Http.FlurlHttpException: Call failed. An error occurred while sending the request
GET https://example.com/my_api/api.php/records/my_table?order=id,desc&size=10 ---> System.Net.Http.HttpRequestException: An error occurred while sending the request
---> System.Net.WebException: Error: TrustFailure (Authentication failed, see inner exception.) ---> System.Security.Authentication.AuthenticationException:
Authentication failed, see inner exception. ---> Mono.Btls.MonoBtlsException: Ssl error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED
at /Users/builder/jenkins/workspace/xamarin-android-d16-1/xamarin-android/external/mono/external/boringssl/ssl/handshake_client.c:1132
at Mono.Btls.MonoBtlsContext.ProcessHandshake () [0x00038] in <74989b9daab94528ac2c4b7da235b9c5>:0 
at Mono.Net.Security.MobileAuthenticatedStream.ProcessHandshake (Mono.Net.Security.AsyncOperationStatus status, System.Boolean renegotiate) [0x000a1] in <74989b9daab94528ac2c4b7da235b9c5>:0 
at (wrapper remoting-invoke-with-check) Mono.Net.Security.MobileAuthenticatedStream.ProcessHandshake(Mono.Net.Security.AsyncOperationStatus,bool)
at Mono.Net.Security.AsyncHandshakeRequest.Run (Mono.Net.Security.AsyncOperationStatus status) [0x00006] in <74989b9daab94528ac2c4b7da235b9c5>:0
at Mono.Net.Security.AsyncProtocolRequest.ProcessOperation (System.Threading.CancellationToken cancellationToken) [0x000ff] in <74989b9daab94528ac2c4b7da235b9c5>:0
at Mono.Net.Security.AsyncProtocolRequest.StartOperation (System.Threading.CancellationToken cancellationToken) [0x0008b] in <74989b9daab94528ac2c4b7da235b9c5>:0 


我尝试过的/我知道的

为什么我的 SSL 握手失败了? Xamarin 与 WPF 有何不同?

你的 Flurl.Http 可能由于使用了 2 种不同的项目类型而失败(.net 标准与 class 库 - 我写的 http 客户端有完全相同的问题)

为 .net 标准尝试不同的 http 客户端。

在任何情况下,您都可以编写自己的 http 客户端并进行调试 - 这是我的建议。
如果你仍然卡住了 - 回信我会帮忙的。

原来是 Apache configuration error. I checked my domain 并注意到一个错误。这是通过在我的 Apache 指令中添加证书的 chain-file 来解决的:

SSLCertificateFile /etc/letsencrypt/live/example.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/example.com/chain.pem

最后一行是遗漏的那一行。奇怪的是浏览器和 WPF 即使没有 chain-file 也信任证书。无论如何,现在它也适用于 Android.

与此同时,我一直在使用这段代码在我的应用程序中禁用 SSL 验证:

// This disables the SSL certificate validity check.
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

该代码不安全,只能用于测试。