ChatGPT解决这个技术问题 Extra ChatGPT

C#忽略证书错误?

在对远程 Web 服务的 Web 服务请求期间,我收到以下错误:

无法为 SSL/TLS 安全通道建立信任关系。 ---> System.Security.Authentication.AuthenticationException:根据验证程序,远程证书无效。

无论如何要忽略此错误并继续吗?

似乎远程证书未签名。

我连接到的站点是 www.czebox.cz - 请随意访问该站点,并注意即使浏览器也会引发安全异常。


P
Peter Lillevold

添加证书验证处理程序。返回 true 将允许忽略验证错误:

ServicePointManager
    .ServerCertificateValidationCallback += 
    (sender, cert, chain, sslPolicyErrors) => true;

这比最初看起来更有用。我在使用托管交换 Web 服务 (EWS) 时遇到了 OP 的问题。我认为我无法使用此答案,因为我无权访问该托管库正在进行的低级 SOAP 调用。但是当我再看一遍时,我意识到 ServicePointManager 是独立存在的。所以,我在初始化 ExchangeService 之前添加了上面的回调,它就像一个魅力。
这是一个如何在全局范围内应用绕过的示例。对于我们所有人来说都是不良做法。 (有时您别无选择)jasig.275507.n4.nabble.com/…
非常感谢,这暂时解决了问题。在 Web Api 的 Startup.cs 中添加此代码
@MarkMeuer 几乎要为我的 EWS API 问题放弃这个解决方案,但后来我看到了你的评论。
@MiguelVeloso 你当然可以自由地投反对票,但请记住,问题和答案都没有讨论这方面的安全性。该主题明确是“如何忽略验证错误”,而不是“我们为什么要/不这样做”,这是一个完全不同的主题。讨论为什么 OP 不应该这样做只会使事情变得混乱,正如评论者指出的那样,在一些合理的情况下你实际上会这样做。所以我们坚持主题并解决问题。
W
Wai Ha Lee

允许所有证书非常强大,但也可能很危险。如果您只想允许有效证书和某些特定证书,可以这样做。

.NET 核心:

using (var httpClientHandler = new HttpClientHandler())
{
    httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, sslPolicyErrors) =>
    {
        if (sslPolicyErrors == SslPolicyErrors.None)
        {
            return true;   //Is valid
        }

        if (cert.GetCertHashString() == "99E92D8447AEF30483B1D7527812C9B7B3A915A7")
        {
            return true;
        }
        return false;
    };

    using (var httpClient = new HttpClient(httpClientHandler))
    {
        var httpResponse = httpClient.GetAsync("https://example.com").Result;
    }
}

.NET 框架:

System.Net.ServicePointManager.ServerCertificateValidationCallback += delegate (
    object sender,
    X509Certificate cert,
    X509Chain chain,
    SslPolicyErrors sslPolicyErrors)
{
    if (sslPolicyErrors == SslPolicyErrors.None)
    {
        return true;   //Is valid
    }

    if (cert.GetCertHashString() == "99E92D8447AEF30483B1D7527812C9B7B3A915A7")
    {
        return true;
    }

    return false;
};

更新:

如何在 Chrome 中获取 cert.GetCertHashString() 值:

点击地址栏中的 SecureNot Secure

https://i.stack.imgur.com/0H3Su.png

https://i.stack.imgur.com/7bPur.png

然后点击证书->详细信息->指纹并复制该值。记得做cert.GetCertHashString().ToLower()

https://i.stack.imgur.com/1j8so.png


@MiguelVeloso 完全同意。这允许跳过检查(希望)一两个证书,而不会完全损害安全性。
如何从证书中获得 Hash String
@Kiquenet 调试代码并从 Immediate window 运行 cert.GetCertHashString() 或在您的浏览器中检查证书 Thumbprint 或检查 MMC(如果它是本地安装的)。
服务器在我们的控制之下,在生产环境中使用@Ogglas 的代码是否仍然安全?使用 TLS/SSL,可以阻止像中间人这样的攻击吗?
.net 核心部分,应该将哪个类放在@Ogglas 中?
A
Amen Ra

IgnoreBadCertificates 方法:

//I use a method to ignore bad certs caused by misc errors
IgnoreBadCertificates();

// after the Ignore call i can do what ever i want...
HttpWebRequest request_data = System.Net.WebRequest.Create(urlquerystring) as HttpWebRequest;

/*
and below the Methods we are using...
*/

/// <summary>
/// Together with the AcceptAllCertifications method right
/// below this causes to bypass errors caused by SLL-Errors.
/// </summary>
public static void IgnoreBadCertificates()
{
    System.Net.ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications);
}  

/// <summary>
/// In Short: the Method solves the Problem of broken Certificates.
/// Sometime when requesting Data and the sending Webserverconnection
/// is based on a SSL Connection, an Error is caused by Servers whoes
/// Certificate(s) have Errors. Like when the Cert is out of date
/// and much more... So at this point when calling the method,
/// this behaviour is prevented
/// </summary>
/// <param name="sender"></param>
/// <param name="certification"></param>
/// <param name="chain"></param>
/// <param name="sslPolicyErrors"></param>
/// <returns>true</returns>
private static bool AcceptAllCertifications(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certification, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
    return true;
} 

我必须再添加一行才能让它与我的代码一起使用(我正在使用 websocket4net)。 System.Net.ServicePointManager.CheckCertificateRevocationList = false;在设置服务器证书验证回调之后。
b
bignum

它失败的原因不是因为它没有签名,而是因为你的客户不信任根证书。除了关闭 SSL 验证,另一种方法是将根 CA 证书添加到您的应用信任的 CA 列表中。

这是您的应用当前不信任的根 CA 证书:

-----BEGIN CERTIFICATE-----
MIIFnDCCBISgAwIBAgIBZDANBgkqhkiG9w0BAQsFADBbMQswCQYDVQQGEwJDWjEs
MCoGA1UECgwjxIxlc2vDoSBwb8WhdGEsIHMucC4gW0nEjCA0NzExNDk4M10xHjAc
BgNVBAMTFVBvc3RTaWdudW0gUm9vdCBRQ0EgMjAeFw0xMDAxMTkwODA0MzFaFw0y
NTAxMTkwODA0MzFaMFsxCzAJBgNVBAYTAkNaMSwwKgYDVQQKDCPEjGVza8OhIHBv
xaF0YSwgcy5wLiBbScSMIDQ3MTE0OTgzXTEeMBwGA1UEAxMVUG9zdFNpZ251bSBS
b290IFFDQSAyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoFz8yBxf
2gf1uN0GGXknvGHwurpp4Lw3ZPWZB6nEBDGjSGIXK0Or6Xa3ZT+tVDTeUUjT133G
7Vs51D6z/ShWy+9T7a1f6XInakewyFj8PT0EdZ4tAybNYdEUO/dShg2WvUyfZfXH
0jmmZm6qUDy0VfKQfiyWchQRi/Ax6zXaU2+X3hXBfvRMr5l6zgxYVATEyxCfOLM9
a5U6lhpyCDf2Gg6dPc5Cy6QwYGGpYER1fzLGsN9stdutkwlP13DHU1Sp6W5ywtfL
owYaV1bqOOdARbAoJ7q8LO6EBjyIVr03mFusPaMCOzcEn3zL5XafknM36Vqtdmqz
iWR+3URAUgqE0wIDAQABo4ICaTCCAmUwgaUGA1UdHwSBnTCBmjAxoC+gLYYraHR0
cDovL3d3dy5wb3N0c2lnbnVtLmN6L2NybC9wc3Jvb3RxY2EyLmNybDAyoDCgLoYs
aHR0cDovL3d3dzIucG9zdHNpZ251bS5jei9jcmwvcHNyb290cWNhMi5jcmwwMaAv
oC2GK2h0dHA6Ly9wb3N0c2lnbnVtLnR0Yy5jei9jcmwvcHNyb290cWNhMi5jcmww
gfEGA1UdIASB6TCB5jCB4wYEVR0gADCB2jCB1wYIKwYBBQUHAgIwgcoagcdUZW50
byBrdmFsaWZpa292YW55IHN5c3RlbW92eSBjZXJ0aWZpa2F0IGJ5bCB2eWRhbiBw
b2RsZSB6YWtvbmEgMjI3LzIwMDBTYi4gYSBuYXZhem55Y2ggcHJlZHBpc3UvVGhp
cyBxdWFsaWZpZWQgc3lzdGVtIGNlcnRpZmljYXRlIHdhcyBpc3N1ZWQgYWNjb3Jk
aW5nIHRvIExhdyBObyAyMjcvMjAwMENvbGwuIGFuZCByZWxhdGVkIHJlZ3VsYXRp
b25zMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQW
BBQVKYzFRWmruLPD6v5LuDHY3PDndjCBgwYDVR0jBHwweoAUFSmMxUVpq7izw+r+
S7gx2Nzw53ahX6RdMFsxCzAJBgNVBAYTAkNaMSwwKgYDVQQKDCPEjGVza8OhIHBv
xaF0YSwgcy5wLiBbScSMIDQ3MTE0OTgzXTEeMBwGA1UEAxMVUG9zdFNpZ251bSBS
b290IFFDQSAyggFkMA0GCSqGSIb3DQEBCwUAA4IBAQBeKtoLQKFqWJEgLNxPbQNN
5OTjbpOTEEkq2jFI0tUhtRx//6zwuqJCzfO/KqggUrHBca+GV/qXcNzNAlytyM71
fMv/VwgL9gBHTN/IFIw100JbciI23yFQTdF/UoEfK/m+IFfirxSRi8LRERdXHTEb
vwxMXIzZVXloWvX64UwWtf4Tvw5bAoPj0O1Z2ly4aMTAT2a+y+z184UhuZ/oGyMw
eIakmFM7M7RrNki507jiSLTzuaFMCpyWOX7ULIhzY6xKdm5iQLjTvExn2JTvVChF
Y+jUu/G0zAdLyeU4vaXdQm1A8AEiJPTd0Z9LAxL6Sq2iraLNN36+NyEK/ts3mPLL

-----END CERTIFICATE-----

您可以使用解码和查看此证书

this certificate decoderanother certificate decoder


是的!这是我的情况,但是如何在没有 VM 的情况下在 Azure 上添加证书?我可以只使用 X509Store API 吗?我明天要试试,但这里欢迎任何信息
W
Wai Ha Lee

绕过 SSL 证书....

HttpClientHandler clientHandler = new HttpClientHandler();
clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };

// Pass the handler to httpclient(from you are calling api)
var client = new HttpClient(clientHandler)

这是 this answer 的精简版,没有添加任何新内容。
d
d.marzo

在客户端配置中禁用 ssl 证书验证。

<behaviors>
   <endpointBehaviors>
      <behavior name="DisableSSLCertificateValidation">
         <clientCredentials>
             <serviceCertificate>
                <sslCertificateAuthentication certificateValidationMode="None" />
              </serviceCertificate>
           </clientCredentials>
        </behavior>

这是 web.config 吗? ASP.NET Core 的任何替代方案?
u
user2347528

这段代码对我有用。我不得不添加 TLS2,因为那是我感兴趣的 URL 所使用的。

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
ServicePointManager.ServerCertificateValidationCallback +=
    (sender, cert, chain, sslPolicyErrors) => { return true; };
using (var client = new HttpClient())
{
    client.BaseAddress = new Uri(UserDataUrl);
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new
      MediaTypeWithQualityHeaderValue("application/json"));
    Task<string> response = client.GetStringAsync(UserDataUrl);
    response.Wait();

    if (response.Exception != null)
    {
         return null;
    }

    return JsonConvert.DeserializeObject<UserData>(response.Result);
}

d
digiogo

旧的,但仍然有帮助......

实现相同行为的另一种好方法是通过配置文件 (web.config)

 <system.net>
    <settings>
      <servicePointManager checkCertificateName="false" checkCertificateRevocationList="false" />
    </settings>
  </system.net>

注意:在 .net full 上测试。


这对我有用。它还有助于 QA/Dev 团队进行测试,同时确保生产配置的安全。谢谢 :)
R
Rimi

这适用于 .Net Core。致电您的 Soap 客户端:

client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication =
                new X509ServiceCertificateAuthentication()
                {
                    CertificateValidationMode = X509CertificateValidationMode.None,
                    RevocationMode = X509RevocationMode.NoCheck
                };  

M
Mario

如果您直接使用套接字并作为客户端进行身份验证,则服务点管理器回调方法将不起作用。这对我有用。请仅用于测试目的。

var activeStream = new SslStream(networkStream, false, (a, b, c, d) => { return true; });
await activeStream.AuthenticateAsClientAsync("computer.local");

这里的关键是在 SSL 流的构造函数中提供远程证书验证回调权限。


N
Nigel Thomas

为了进一步扩展 BIGNUM 的帖子 - 理想情况下,您需要一个能够模拟您将在生产中看到的条件的解决方案,并且修改您的代码不会这样做,并且如果您在部署之前忘记取出代码,可能会很危险。

您将需要某种自签名证书。如果您知道自己在做什么,则可以使用发布的二进制 BIGNUM,但如果不知道,您可以去寻找证书。如果您使用的是 IIS Express,那么您已经拥有其中之一,您只需找到它。打开 Firefox 或任何您喜欢的浏览器,然后访问您的开发网站。您应该能够从 URL 栏中查看证书信息,并且根据您的浏览器,您应该能够将证书导出到文件中。

接下来,打开 MMC.exe,并添加证书管理单元。将您的证书文件导入受信任的根证书颁发机构存储中,这就是您所需要的。重要的是要确保它进入那家商店,而不是像“个人”这样的其他商店。如果您不熟悉 MMC 或证书,有许多网站提供有关如何执行此操作的信息。

现在,您的计算机作为一个整体将隐式信任它自己生成的任何证书,您无需添加代码来专门处理此问题。当您转移到生产环境时,只要您在那里安装了适当的有效证书,它将继续工作。不要在生产服务器上执行此操作 - 这会很糟糕,并且它不适用于服务器本身以外的任何其他客户端。