有没有一种方法可以使用 FtpWebRequest 在 C# 中使用客户端证书对 FTP 进行身份验证?
Is there a way to use FtpWebRequest to authenticate to FTP using client certificates in C#?
我正在尝试将文件上传到 FTP 服务器,我需要使用客户端证书进行身份验证,而不是用户名和密码。
var fullFtpPath = String.Concat(ftpItem.FtpAddress, "/", record, ".txt");
FtpWebRequest request = (FtpWebRequest) WebRequest.Create(fullFtpPath);
request.Credentials = new NetworkCredential(ftpItem.Username, ftpItem.Password);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.UseBinary = true;
request.UsePassive = ftpItem.UsePassive;
request.EnableSsl = ftpItem.UseSSL;
request.ContentLength = bytes.Length;
using(Stream s = request.GetRequestStream()) {
s.Write(bytes, 0, bytes.Length);
}
FtpWebResponse response = (FtpWebResponse) request.GetResponse();
Debug.WriteLine("Upload File Complete, status {0}", response.StatusDescription);
db.LogExport(siteId, fullFtpPath, record, true, response.StatusDescription);
response.Close();
以上是我当前的代码,但我不确定如何实现证书身份验证,或者是否有可能实现。我必须创建证书吗?或者服务器会给我一个证书,我会在我的请求中设置它?
- 使用
FtpWebRequest.ClientCertificates
property指定用于身份验证的证书
- 证书属于type
X509Certificate
- 您可以自己构建证书(从字节数组或从文件导入),或者在证书存储中查找 (
X509Store
)
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://ftp.example.com");
request.Credentials = new NetworkCredential("username", "");
// Query certificate from store
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
const string tp = "2b6f8ac51a85cbaf429474a55304313968667611";
X509Certificate2 cert2 =
store.Certificates.Find(X509FindType.FindByThumbprint, tp, true)[0];
store.Close();
// Add certificate into request
request.ClientCertificates.Add(cert2);
您可以为此使用 ComponentPro。
This code example 解释了如何使用证书对客户端进行身份验证:
using System;
using System.Security.Cryptography.X509Certificates;
using ComponentPro.Net;
...
public void HandleCertificateRequiredEvent()
{
// Create a new instance.
Ftp client = new Ftp();
client.CertificateRequired += client_CertificateRequired;
// Connect to the FTP server.
client.Connect("myserver", 21, FtpSecurityMode.Explicit);
// Authenticate.
client.Authenticate("userName", "password");
// Do something here...
client.DownloadFile("/my remote file.dat", "my local file");
// Disconnect.
client.Disconnect();
}
void client_CertificateRequired(object sender, ComponentPro.Security.CertificateRequiredEventArgs e)
{
// Load certificates from the local machine.
X509Store my = new X509Store(StoreName.My, StoreLocation.CurrentUser);
my.Open(OpenFlags.ReadOnly);
// Retrieve a list of available certificates.
X509Certificate2Collection certs = my.Certificates;
// If no certificate found, return.
if (certs.Count == 0)
{
e.Certificates = null;
return;
}
// Show all certificates.
Console.WriteLine("Select certificate:");
for (int i = 0; i <= certs.Count; i++)
{
if (i == 0)
{
Console.WriteLine(string.Format("{0}. [Nothing, skip this step]", i));
continue;
}
Console.WriteLine(string.Format("{0}. {1}", i, certs[i - 1].SubjectName.Name));
}
// And ask user to choose an appropriate certificate.
while (true)
{
Console.Write(string.Format("Select certificate [0 - {0}]: ", certs.Count));
int certIndex;
try
{
certIndex = int.Parse(Console.ReadLine());
}
catch
{
Console.WriteLine("ERROR: Wrong certificate index input!");
continue;
}
if (certIndex > 0 && certIndex <= certs.Count)
{
e.Certificates = new X509Certificate2Collection(certs[certIndex]);
return;
}
if (certIndex == 0)
break;
Console.WriteLine(string.Format("ERROR: You must enter number between 0 and {0}.", certs.Count));
}
}
ComponentPro 也很好用 with FtpWebRequest:
using System;
using System.IO;
using System.Net;
...
// Register FtpWebRequest for the specified schema.
WebRequest.RegisterPrefix("ftp://", ComponentPro.Net.FtpWebRequest.Creator);
Console.WriteLine("Sending request...");
// Create a WebRequest for the specified URL.
WebRequest request = WebRequest.Create("ftp://ftp.example.net/pub/myfile.zip");
// Send the WebRequest and waits for a response.
WebResponse response = request.GetResponse();
// Get remote file stream for downloading.
Stream remoteFileStream = response.GetResponseStream();
Stream localFileStream = File.Create("myfile.zip");
// Create a new buffer to download.
byte[] buffer = new byte[1024];
int n;
do
{
// Read data from the remote file stream.
n = remoteFileStream.Read(buffer, 0, buffer.Length);
// Write to the local file stream.
localFileStream.Write(buffer, 0, n);
} while (n > 0);
Console.WriteLine("Response Received.");
localFileStream.Close();
// Release the resources of the response.
remoteFileStream.Close();
我正在尝试将文件上传到 FTP 服务器,我需要使用客户端证书进行身份验证,而不是用户名和密码。
var fullFtpPath = String.Concat(ftpItem.FtpAddress, "/", record, ".txt");
FtpWebRequest request = (FtpWebRequest) WebRequest.Create(fullFtpPath);
request.Credentials = new NetworkCredential(ftpItem.Username, ftpItem.Password);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.UseBinary = true;
request.UsePassive = ftpItem.UsePassive;
request.EnableSsl = ftpItem.UseSSL;
request.ContentLength = bytes.Length;
using(Stream s = request.GetRequestStream()) {
s.Write(bytes, 0, bytes.Length);
}
FtpWebResponse response = (FtpWebResponse) request.GetResponse();
Debug.WriteLine("Upload File Complete, status {0}", response.StatusDescription);
db.LogExport(siteId, fullFtpPath, record, true, response.StatusDescription);
response.Close();
以上是我当前的代码,但我不确定如何实现证书身份验证,或者是否有可能实现。我必须创建证书吗?或者服务器会给我一个证书,我会在我的请求中设置它?
- 使用
FtpWebRequest.ClientCertificates
property指定用于身份验证的证书 - 证书属于type
X509Certificate
- 您可以自己构建证书(从字节数组或从文件导入),或者在证书存储中查找 (
X509Store
)
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://ftp.example.com");
request.Credentials = new NetworkCredential("username", "");
// Query certificate from store
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
const string tp = "2b6f8ac51a85cbaf429474a55304313968667611";
X509Certificate2 cert2 =
store.Certificates.Find(X509FindType.FindByThumbprint, tp, true)[0];
store.Close();
// Add certificate into request
request.ClientCertificates.Add(cert2);
您可以为此使用 ComponentPro。 This code example 解释了如何使用证书对客户端进行身份验证:
using System;
using System.Security.Cryptography.X509Certificates;
using ComponentPro.Net;
...
public void HandleCertificateRequiredEvent()
{
// Create a new instance.
Ftp client = new Ftp();
client.CertificateRequired += client_CertificateRequired;
// Connect to the FTP server.
client.Connect("myserver", 21, FtpSecurityMode.Explicit);
// Authenticate.
client.Authenticate("userName", "password");
// Do something here...
client.DownloadFile("/my remote file.dat", "my local file");
// Disconnect.
client.Disconnect();
}
void client_CertificateRequired(object sender, ComponentPro.Security.CertificateRequiredEventArgs e)
{
// Load certificates from the local machine.
X509Store my = new X509Store(StoreName.My, StoreLocation.CurrentUser);
my.Open(OpenFlags.ReadOnly);
// Retrieve a list of available certificates.
X509Certificate2Collection certs = my.Certificates;
// If no certificate found, return.
if (certs.Count == 0)
{
e.Certificates = null;
return;
}
// Show all certificates.
Console.WriteLine("Select certificate:");
for (int i = 0; i <= certs.Count; i++)
{
if (i == 0)
{
Console.WriteLine(string.Format("{0}. [Nothing, skip this step]", i));
continue;
}
Console.WriteLine(string.Format("{0}. {1}", i, certs[i - 1].SubjectName.Name));
}
// And ask user to choose an appropriate certificate.
while (true)
{
Console.Write(string.Format("Select certificate [0 - {0}]: ", certs.Count));
int certIndex;
try
{
certIndex = int.Parse(Console.ReadLine());
}
catch
{
Console.WriteLine("ERROR: Wrong certificate index input!");
continue;
}
if (certIndex > 0 && certIndex <= certs.Count)
{
e.Certificates = new X509Certificate2Collection(certs[certIndex]);
return;
}
if (certIndex == 0)
break;
Console.WriteLine(string.Format("ERROR: You must enter number between 0 and {0}.", certs.Count));
}
}
ComponentPro 也很好用 with FtpWebRequest:
using System;
using System.IO;
using System.Net;
...
// Register FtpWebRequest for the specified schema.
WebRequest.RegisterPrefix("ftp://", ComponentPro.Net.FtpWebRequest.Creator);
Console.WriteLine("Sending request...");
// Create a WebRequest for the specified URL.
WebRequest request = WebRequest.Create("ftp://ftp.example.net/pub/myfile.zip");
// Send the WebRequest and waits for a response.
WebResponse response = request.GetResponse();
// Get remote file stream for downloading.
Stream remoteFileStream = response.GetResponseStream();
Stream localFileStream = File.Create("myfile.zip");
// Create a new buffer to download.
byte[] buffer = new byte[1024];
int n;
do
{
// Read data from the remote file stream.
n = remoteFileStream.Read(buffer, 0, buffer.Length);
// Write to the local file stream.
localFileStream.Write(buffer, 0, n);
} while (n > 0);
Console.WriteLine("Response Received.");
localFileStream.Close();
// Release the resources of the response.
remoteFileStream.Close();