我正在尝试使用带有SSL证书的FTP作为身份验证来读取远程站点(不受我控制)的目录内容。
但是当我运行下面的示例代码时,它失败并显示错误"根据验证程序,远程证书无效。"。它在此行(FtpWebResponse)ftpRequest.GetResponse()
上失败。
我不希望看到这个错误。我希望它能验证SSL链。
我可以通过以下方式解决错误:
当我通过代码阅读.p12文件时,它在X509Certificate2Collection中提供了2个证书,或者当通过SSL向导导入时,在本地SSL机器商店中提供了两个证书。一个是根证书颁发机构(CA)和客户端证书。
两个证书都有效(日期等)。
我不确定如何告诉X509Certificate2Collection证书[1](客户端证书)在链中的证书[0](CA)之后。我认为这是我的问题所以我该如何实现呢?
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
namespace Demo
{
class Program
{
static void Main(string[] args)
{
X509Certificate2Collection certificateCollection = new X509Certificate2Collection();
using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Demo.SomeSSLCertificate.p12")) //Embedded resource. In Solution Explorer window in VS, right click file and set build action as "Embedded Resource"
{
byte[] bytes = new byte[stream.Length];
stream.Read(bytes, 0, bytes.Length);
certificateCollection.Import(bytes, "SomeSSLPassword", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
}
string Host = "www.somedomain.com";
int Port = 21;
string remoteDirectory = "SomeDirectory";
string ftpPath = String.Format("ftp://{0}:{1}/{2}", Host, Port, remoteDirectory);
FtpWebRequest ftpRequest = (FtpWebRequest)FtpWebRequest.Create(ftpPath);
ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory;
ftpRequest.UseBinary = false;
ftpRequest.UsePassive = true;
ftpRequest.KeepAlive = true;
ftpRequest.Credentials = new NetworkCredential("SomeUsername", "SomePassword");
ftpRequest.EnableSsl = true;
ftpRequest.ClientCertificates.AddRange(certificateCollection);
List<string> entries = new List<string>();
//ServicePointManager.ServerCertificateValidationCallback =
//delegate(object s,
//X509Certificate certificate,
//X509Chain chain,
//SslPolicyErrors sslPolicyErrors)
//{
// return true;
//};
using (FtpWebResponse response = (FtpWebResponse)ftpRequest.GetResponse())
{
using (Stream responseStream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(responseStream))
{
string details = reader.ReadToEnd();
using (StringReader stringReader = new StringReader(details))
{
string entry = String.Empty;
while ((entry = stringReader.ReadLine()) != null)
{
entries.Add(remoteDirectory + "/" + entry);
}
}
}
}
}
entries.ForEach(entry => Console.WriteLine(entry));
Console.WriteLine("Finished");
Console.ReadKey();
}
}
}
干杯
凯尔