如何修复 "Remote certificate is invalid according to the validation procedure"
How to fix "Remote certificate is invalid according to the validation procedure"
我打算尝试通过 Mailkit 发送电子邮件,但 运行 遇到了来自“System.Security.Authentication.AuthenticationException”的错误问题,即“根据验证程序,远程证书无效”(t 运行slated from danish) 我的邮件服务器运行 SSL TLS,并且 TLS 支持版本 1.2 和 1.3。我的代码如下:我不希望它有太多代码 - 但我不知道在哪里增强代码以便它可以正确处理 SSL :-(
错误发生在行“client.Connect("servername", 587, true);"
所以我的问题是:如何通过 Mailkit 避免此错误消息?
public void SendMail(string AFromMailAdr, string AFromName, string AToMailAdr, string AToName, string ASubject, string ABody)
{
MimeMessage message = new MimeMessage();
...
using (var client = new MailKit.Net.Smtp.SmtpClient())
{
client.Timeout = 30000;
client.Connect("servername", 587, true);
client.Authenticate("Username", "password");
client.Send(message);
client.Disconnect(true);
}
}
直到现在我已经用 google 搜索了很多次都没有找到正确的答案 - 所以我很乐意在这里问一下。
公平地说,根本问题应该是checked/corrected。
您可以使用 a ServerCertificateValidationCallback
控制 MailKit 如何进行服务器证书验证
出于调试目的,您可以在回调函数中return true;
。
MailKit 文档中的代码:
using (var client = new MailKit.Net.Smtp.SmtpClient())
{
// Set our custom SSL certificate validation callback.
client.ServerCertificateValidationCallback = MySslCertificateValidationCallback;
client.Timeout = 30000;
client.Connect("servername", 587, true);
client.Authenticate("Username", "password");
client.Send(message);
client.Disconnect(true);
}
static bool MySslCertificateValidationCallback (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
// If there are no errors, then everything went smoothly.
if (sslPolicyErrors == SslPolicyErrors.None)
return true;
// Note: MailKit will always pass the host name string as the `sender` argument.
var host = (string) sender;
if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) != 0) {
// This means that the remote certificate is unavailable. Notify the user and return false.
Console.WriteLine ("The SSL certificate was not available for {0}", host);
return false;
}
if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) != 0) {
// This means that the server's SSL certificate did not match the host name that we are trying to connect to.
var certificate2 = certificate as X509Certificate2;
var cn = certificate2 != null ? certificate2.GetNameInfo (X509NameType.SimpleName, false) : certificate.Subject;
Console.WriteLine ("The Common Name for the SSL certificate did not match {0}. Instead, it was {1}.", host, cn);
return false;
}
// The only other errors left are chain errors.
Console.WriteLine ("The SSL certificate for the server could not be validated for the following reasons:");
// The first element's certificate will be the server's SSL certificate (and will match the `certificate` argument)
// while the last element in the chain will typically either be the Root Certificate Authority's certificate -or- it
// will be a non-authoritative self-signed certificate that the server admin created.
foreach (var element in chain.ChainElements) {
// Each element in the chain will have its own status list. If the status list is empty, it means that the
// certificate itself did not contain any errors.
if (element.ChainElementStatus.Length == 0)
continue;
Console.WriteLine ("\u2022 {0}", element.Certificate.Subject);
foreach (var error in element.ChainElementStatus) {
// `error.StatusInformation` contains a human-readable error string while `error.Status` is the corresponding enum value.
Console.WriteLine ("\t\u2022 {0}", error.StatusInformation);
}
}
return false;
}
我打算尝试通过 Mailkit 发送电子邮件,但 运行 遇到了来自“System.Security.Authentication.AuthenticationException”的错误问题,即“根据验证程序,远程证书无效”(t 运行slated from danish) 我的邮件服务器运行 SSL TLS,并且 TLS 支持版本 1.2 和 1.3。我的代码如下:我不希望它有太多代码 - 但我不知道在哪里增强代码以便它可以正确处理 SSL :-(
错误发生在行“client.Connect("servername", 587, true);"
所以我的问题是:如何通过 Mailkit 避免此错误消息?
public void SendMail(string AFromMailAdr, string AFromName, string AToMailAdr, string AToName, string ASubject, string ABody)
{
MimeMessage message = new MimeMessage();
...
using (var client = new MailKit.Net.Smtp.SmtpClient())
{
client.Timeout = 30000;
client.Connect("servername", 587, true);
client.Authenticate("Username", "password");
client.Send(message);
client.Disconnect(true);
}
}
直到现在我已经用 google 搜索了很多次都没有找到正确的答案 - 所以我很乐意在这里问一下。
公平地说,根本问题应该是checked/corrected。
您可以使用 a ServerCertificateValidationCallback
控制 MailKit 如何进行服务器证书验证出于调试目的,您可以在回调函数中return true;
。
MailKit 文档中的代码:
using (var client = new MailKit.Net.Smtp.SmtpClient())
{
// Set our custom SSL certificate validation callback.
client.ServerCertificateValidationCallback = MySslCertificateValidationCallback;
client.Timeout = 30000;
client.Connect("servername", 587, true);
client.Authenticate("Username", "password");
client.Send(message);
client.Disconnect(true);
}
static bool MySslCertificateValidationCallback (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
// If there are no errors, then everything went smoothly.
if (sslPolicyErrors == SslPolicyErrors.None)
return true;
// Note: MailKit will always pass the host name string as the `sender` argument.
var host = (string) sender;
if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) != 0) {
// This means that the remote certificate is unavailable. Notify the user and return false.
Console.WriteLine ("The SSL certificate was not available for {0}", host);
return false;
}
if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) != 0) {
// This means that the server's SSL certificate did not match the host name that we are trying to connect to.
var certificate2 = certificate as X509Certificate2;
var cn = certificate2 != null ? certificate2.GetNameInfo (X509NameType.SimpleName, false) : certificate.Subject;
Console.WriteLine ("The Common Name for the SSL certificate did not match {0}. Instead, it was {1}.", host, cn);
return false;
}
// The only other errors left are chain errors.
Console.WriteLine ("The SSL certificate for the server could not be validated for the following reasons:");
// The first element's certificate will be the server's SSL certificate (and will match the `certificate` argument)
// while the last element in the chain will typically either be the Root Certificate Authority's certificate -or- it
// will be a non-authoritative self-signed certificate that the server admin created.
foreach (var element in chain.ChainElements) {
// Each element in the chain will have its own status list. If the status list is empty, it means that the
// certificate itself did not contain any errors.
if (element.ChainElementStatus.Length == 0)
continue;
Console.WriteLine ("\u2022 {0}", element.Certificate.Subject);
foreach (var error in element.ChainElementStatus) {
// `error.StatusInformation` contains a human-readable error string while `error.Status` is the corresponding enum value.
Console.WriteLine ("\t\u2022 {0}", error.StatusInformation);
}
}
return false;
}