Xamarin 中的 SSL 握手失败
SSL handshake fails in Xamarin
我正在尝试访问我的 RESTful API 以从 MySQL 数据库中检索数据。在我的 C# WPF 项目中,一切都已设置并完美运行。但是当在 Xamarin Forms(为 Android 构建)中使用完全相同的代码时,我无法与我的服务器成功进行 SSL 握手。
服务器详细信息
- Let's Encrypt SSL 证书(绝对有效)
- Apache BasicAuth (.htaccess)
- 仅限 HTTPS(重写 HTTP),因此端口 443
- REST API:php-crud-api(由 mevdschee)访问 MariaDB 10.3
我正在使用 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
我尝试过的/我知道的
- 代码 在 WPF
中完美运行
- 完全相同的代码(复制粘贴)不在 Xamarin Forms 中工作(在 Android Pie 上测试)
- 在模拟器或专用设备中不起作用
- 通过浏览器访问 REST API 工作 并按预期交付结果(在我的 PC、Chrome 中的模拟器和我专用的 Android)
- 在项目属性 -> Android 选项 -> 高级下更改 HttpClient 实现或 SSL/TLS 实现没有帮助
为什么我的 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; };
该代码不安全,只能用于测试。
我正在尝试访问我的 RESTful API 以从 MySQL 数据库中检索数据。在我的 C# WPF 项目中,一切都已设置并完美运行。但是当在 Xamarin Forms(为 Android 构建)中使用完全相同的代码时,我无法与我的服务器成功进行 SSL 握手。
服务器详细信息
- Let's Encrypt SSL 证书(绝对有效)
- Apache BasicAuth (.htaccess)
- 仅限 HTTPS(重写 HTTP),因此端口 443
- REST API:php-crud-api(由 mevdschee)访问 MariaDB 10.3
我正在使用 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
我尝试过的/我知道的
- 代码 在 WPF
- 完全相同的代码(复制粘贴)不在 Xamarin Forms 中工作(在 Android Pie 上测试)
- 在模拟器或专用设备中不起作用
- 通过浏览器访问 REST API 工作 并按预期交付结果(在我的 PC、Chrome 中的模拟器和我专用的 Android)
- 在项目属性 -> Android 选项 -> 高级下更改 HttpClient 实现或 SSL/TLS 实现没有帮助
为什么我的 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; };
该代码不安全,只能用于测试。