c# - 无法为 SSL/TLS 安全通道建立信任关系 - Windows Server 2012 R2
问题描述
我知道 StackOverflow 和其他资源上有很多关于此错误的信息,但它在我的开发机器上运行良好,现在在客户环境 Windows Server 2012 上运行。这是我的代码。
public sealed class Certificates
{
private static bool subscribed = false;
private static Certificates instance = null;
private static readonly object padlock = new object();
private Certificates() { }
public static Certificates Instance
{
get
{
lock (padlock)
{
if (instance == null)
instance = new Certificates();
return instance;
}
}
}
public void GetCertificatesAutomatically()
{
if (!subscribed)
{
ServicePointManager.ServerCertificateValidationCallback +=
RemoteCertificateValidationCallback;
//new RemoteCertificateValidationCallback((sender, certificate, chain, policyErrors) => { return true; });
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 |
SecurityProtocolType.Tls |
SecurityProtocolType.Tls11 |
SecurityProtocolType.Tls12;
ServicePointManager.MaxServicePointIdleTime = 0;
subscribed = true;
}
}
private static bool RemoteCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
// Return true if the server certificate is ok
if (sslPolicyErrors == SslPolicyErrors.None)
return true;
bool acceptCertificate = true;
StringBuilder msg = new StringBuilder("The server could not be validate for the following reason():");
// The server did not present a certificate
if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) == SslPolicyErrors.RemoteCertificateNotAvailable)
{
msg.AppendLine(" - The server did not present a certificate.");
acceptCertificate = false;
}
else
{
// The certificate does not math the server name
if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) == SslPolicyErrors.RemoteCertificateNameMismatch)
{
msg.AppendLine(" - The certificate name does not match the authenticated name.");
acceptCertificate = false;
}
// There is som other problem with certificate
if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) == SslPolicyErrors.RemoteCertificateChainErrors)
{
foreach (X509ChainStatus item in chain.ChainStatus)
{
if (item.Status != X509ChainStatusFlags.RevocationStatusUnknown &&
item.Status != X509ChainStatusFlags.OfflineRevocation)
{
SLICLog.Error($" - {item.StatusInformation}.");
break;
}
if (item.Status != X509ChainStatusFlags.NoError)
{
msg.AppendLine($" - {item.StatusInformation}.");
acceptCertificate = false;
}
}
}
}
// if validation failed, write log
if (!acceptCertificate)
{
acceptCertificate = true;
}
return acceptCertificate;
}
}
然后我使用了下一个代码
Host = new Uri(credential.Domain);
if (Host.Scheme.Contains("https"))
Certificates.Instance.GetCertificatesAutomatically();
using (HttpWebResponse httpWebResponse = httpRequest.GetResponse() as HttpWebResponse)
using (var response = httpWebResponse.GetResponseStream())
using (var sr = new StreamReader(response))
{
token = JsonConvert.DeserializeObject<SessionInternal>(sr.ReadToEnd());
if (token != null)
{
Authorized = true;
token.Exprired = DateTime.Now.AddSeconds(Convert.ToDouble(token.expires_in));
}
}
问题是 ServerCertificateValidationCallback 在环境机器上被忽略(我从我添加的日志中知道它只是为了调试)。
在一个网站上,我读到微软不允许忽略服务器机器上的自签名证书,但不确定。相同的代码适用于 Windows10,不适用于 Windows Server 2012,API 服务器的设置也相同,我的意思是主机 url 和凭据是相同的。.NET 框架 4.7.2
更新:
我不知道为什么,但是另一个具有自签名证书的服务器可以工作,我的意思是我在环境服务器上运行代码以与另一个 API 服务器(它是另一种 API)一起工作,并且调用了 ServerCertificateValidationCallback 委托。我试图通过 Wireshark 研究网络,这是客户端/服务器之间连接不良的一部分 这是与另一台服务器的正常连接, 我很困惑,但代码相同,只有 API 服务器的 IP 不同,行为不同
解决方案
我遇到了同样的问题 - Windows 10 也可以正常工作,Server 2012 R2 不能。我已经尝试了从 .Net 4.6 到 4.7.2 到 4.8 的所有内容,它在 Win 10 中运行良好,但在 Win Server 2012 R2 中运行良好。这是从客户端的角度来看(即 Win Server 2012 R2 运行失败的客户端软件)。我正在访问的站点具有有效的仅限 GoDaddy TLS 1.2 证书。
推荐阅读
- haskell - 通过数据分析学习 Haskell 示例中的类型不匹配
- javascript - 在字典中查找第三个元素值
- asp.net-core - 无法通过 ASP.NET Core 2.0 的环境变量更改侦听端口
- sql - 使用 sql 表中的 powershell 将数据写入 excel
- windows - 批量列出所有类型文件的组合大小
- javascript - 我需要帮助执行 if 函数 - 我的“if 函数”以及我的“else 函数”都执行了吗?
- networking - 格式正确的 MAC 地址无效
- python - 训练后 TensorFlow Hessian 矩阵未更新
- python - 熊猫和日期时间
- python - 使用 PyCapture2 读取 MONO 16 位图像