我有一个 .NET 客户端应用程序,它尝试将文件通过 ftp 传输到具有自签名 TLS/SSL 证书的 FTP 站点。此 FTP 站点在 Windows 7 Enterprise、IIS 7 上运行。我收到以下错误:
根据验证程序,远程证书无效
我已经尝试在受信任的根证书中安装证书,但这仍然不起作用。
我已经在此处提到的一些帖子的代码中使用了委托回调 - 它有效。但我不想在我的生产代码中使用它。
同样在生产中,我们的一些客户正在使用自签名证书。
有关如何解决此问题的任何想法?
我有一个 .NET 客户端应用程序,它尝试将文件通过 ftp 传输到具有自签名 TLS/SSL 证书的 FTP 站点。此 FTP 站点在 Windows 7 Enterprise、IIS 7 上运行。我收到以下错误:
根据验证程序,远程证书无效
我已经尝试在受信任的根证书中安装证书,但这仍然不起作用。
我已经在此处提到的一些帖子的代码中使用了委托回调 - 它有效。但我不想在我的生产代码中使用它。
同样在生产中,我们的一些客户正在使用自签名证书。
有关如何解决此问题的任何想法?
您必须覆盖证书检查,以便它们始终被认为是好的。这不会阻止通道保持 SSL 保护。
Uri target = new Uri("ftp://yourUri");
string fileName = @"fullPathOfYourFile";
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(target);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential("user", "password");
request.EnableSsl = true;
//overwrite the certificate checks
ServicePointManager.ServerCertificateValidationCallback =
(s, certificate, chain, sslPolicyErrors) => true;
// Copy the contents of the file to the request stream
//....
@Luca 投票最多的答案盲目地接受任何证书。这是一个安全漏洞。
实施ServicePointManager.ServerCertificateValidation
回调时,应验证证书。例如,通过根据已知值检查证书的哈希:
using System.Net;
using System.Net.Security;
using System.Security.Cryptography;
ServicePointManager.ServerCertificateValidationCallback +=
(sender, certificate, chain, errors) =>
{
return
(errors == SslPolicyErrors.None) ||
certificate.GetCertHashString(HashAlgorithmName.SHA256).Equals(
"EB8E0B28AE064ED58CBED9DAEB46CFEB3BD7ECA677...");
};
对于需要的X509Certificate.GetCertHashString
重载HashAlgorithmName.SHA256
,您需要 .NET 4.8。在旧版本上,使用返回 SHA-1 哈希的无参数重载。
基于当您知道无效证书是安全的时测试 X509Certificate.Thumbprint 属性是否安全?
对于 VB.NET 版本的代码,请参阅在 VB.NET 中接受自签名 TLS/SSL 证书。
如果您尝试连接到 IP 地址而不是域名,您也会收到此错误。由于证书是发给域名的,所以IP地址不起作用。
我通过 .NET 遇到了同样的问题,我的帐户甚至本地计算机帐户都信任证书根和链。所以证书是金色的。
对我来说,我使用了错误的主机名。我使用的是完全限定名称(并且到达了正确的位置),但证书实际上是颁发给不同的别名的。因此,请确保您的服务器名称与证书上的内容完全匹配。
检查这篇文章,这就是我找到答案的方式......也许事件订阅也是你需要的......
http://www.limilabs.com/blog/the-remote-certificate-is-invalid-according-to-the-validation-procedure
如果在尝试建立 SSL 连接时收到“根据验证程序,远程证书无效”异常,很可能您的服务器证书是自签名的。 解决问题:
步骤 1:启用 ssl 属性:
request.EnableSsl = true;
Step2:覆盖证书检查:
ServicePointManager.ServerCertificateValidationCallback =
(s, certificate, chain, sslPolicyErrors) => true;
例如:
public static string uploadFtpFile(string folderName, string fileName)
{
try
{
FtpWebRequest request;
string absoluteFileName = Path.GetFileName(fileName);
request = WebRequest.Create(new Uri(string.Format(@"ftp://{0}/{1}/{2}", "194.11.11.11", folderName, absoluteFileName))) as FtpWebRequest;
request.Method = WebRequestMethods.Ftp.UploadFile;
request.UseBinary = true;
request.UsePassive = true;
request.KeepAlive = true;
request.Credentials = new NetworkCredential("user", "pass");
request.EnableSsl = true;
ServicePointManager.ServerCertificateValidationCallback =
(s, certificate, chain, sslPolicyErrors) => true;
request.ConnectionGroupName = "group";
using (FileStream fs = File.OpenRead(fileName))
{
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
fs.Close();
Stream requestStream = request.GetRequestStream();
requestStream.Write(buffer, 0, buffer.Length);
requestStream.Flush();
requestStream.Close();
}
return "1";
}
catch (Exception ax)
{
return "0" + ax.Message;
}
}
用法:
private void button17_Click(object sender, EventArgs e)
{
string res += uploadFtpFile("", @"C:\a\test.txt");
MessageBox.Show(res);//"1" mean true...
}