【发布时间】:2021-09-08 01:30:06
【问题描述】:
我目前正在将代码从 .NET 4.7.2 升级到 .NET 5。当下面的代码在 NET 4.7.2 下运行时,它成功连接到网络服务器,在 NET 5 下它会抛出此异常:
Exception: "The SSL connection could not be established, see inner exception."
-> InnerException: "Authentication failed, see inner exception."
-> InnerException: "An unknown error occurred while processing"
为什么在 .NET 4.7.2 和 .NET 5 之间会有不同的行为?
如果您不提供证书,也会遇到同样的例外情况。我尝试从 .pfx 文件和本地机器的 X509Store 加载证书。我还让公司的其他开发人员尝试过,他们得到了相同的结果。
代码在 Windows 10 上运行,使用 VS 2019,但在部署到 Windows IIS 服务器时会出现同样的问题。
请帮忙,因为我没有想法
using RestSharp;
using System;
using System.Linq;
using System.Net;
using System.Security.Cryptography.X509Certificates;
namespace SwipeTestNet5
{
class Program
{
static void Main(string[] args)
{
try
{
// certificate store fetching
var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);
// getting the certificate from the store based on the app setting certificateName
// !! obviously this url is not the real one
var certificateName = "test-cert-name";
// the following line will error if there are certificates with the same friendly name... you shouldn't have let this happen
var cert = store.Certificates.Cast<X509Certificate2>().SingleOrDefault(c => c.FriendlyName == certificateName);
if (cert == null)
throw new Exception("Could not find certificate with name: " + certificateName);
// Handle any certificate errors on the certificate from the server.
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
// !! obviously this url is not the real one
var url = "https://test.com.au/api";
var client = new RestClient(url);
var request = new RestRequest(Method.GET);
client.ClientCertificates = new X509CertificateCollection(new[] { cert });
// Handle any certificate errors on the certificate from the server.
// !! When ran under .NET 4.7.2 this callback is triggred, under .NET 5 it never reaches
client.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
// !! obviously this url is not the real parameters
var parameters = new
{
param1 = "a",
param2 = "b",
param3 = "c"
};
request.AddObject(parameters);
var response = client.Execute(request);
// !! Under NET 4.7.2 response.ErrorException is null and continues
// !! Under NET 5 the response.ErrorException is populated with this:
// ErrorException: "The SSL connection could not be established, see inner exception."
// -> InnerException: "Authentication failed, see inner exception."
// -> InnerException: "An unknown error occurred while processing the certificate."
if (response.ErrorException != null)
throw response.ErrorException;
// !! NET 4.7.2 gets to here without issue
if (response.StatusCode != HttpStatusCode.OK)
{
Exception ex = new Exception($"Error calling {client}");
ex.Data.Add("xml", response.Content);
ex.Data.Add("status code", response.StatusCode);
ex.Data.Add("param1", parameters.param1);
ex.Data.Add("param2", parameters.param2);
ex.Data.Add("param3", parameters.param3);
throw ex;
}
Console.WriteLine("Success");
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
【问题讨论】:
-
请用标准
HttpClient重试,看看是否有同样的问题。 -
另外,在 .NET 5 中,应该没有必要乱用
ServicePointManager.SecurityProtocol- .NET 支持并将自动使用适当的 SSL/TLS 协议。 -
@IanKemp 我用 HttpClient 得到了同样的行为
标签: c# .net ssl x509certificate .net-5