I am trying to download a file from my FTP Server but from my production server (from my laptop I am able to download the file) I get the error "A call to SSPI failed" and the inner exception "The message received was unexpected or badly formatted". This my code:
var ftpServer = "ftp://xxx.yyy.zz/";
var ftpUsername = "aaaaa";
var ftpPassword = "bbbbb";
var downloadedFilePath = "c:\\temp\\";
var downloadedFileName = "file.xls";
FtpWebRequest request = null;
ServicePointManager.SecurityProtocol = ServicePointManager.SecurityProtocol | SecurityProtocolType.Tls12;
ServicePointManager.ServerCertificateValidationCallback = delegate (object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) {
return true;
};
// Get the object used to communicate with the server.
request = (FtpWebRequest)WebRequest.Create(ftpServer "file_on_ftp_server.xls");
// download the file
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.Credentials = new NetworkCredential(ftpUsername, ftpPassword);
request.EnableSsl = true;
request.KeepAlive = false;
FtpWebResponse response = (FtpWebResponse)request.GetResponse(); // <--- ERROR
Stream responseStream = response.GetResponseStream();
FileStream writer = new FileStream(downloadedFilePath downloadedFileName, FileMode.Create);
CodePudding user response:
To use SSL certificate inside .Net framework we need to provide both certificate and its corresponding private key together. To achieve this we need to use p12(.pfx) file which combined this two. In my project, I have used self-signed certificate using OpenSSL so I used below command to combine certificate and private key
pkcs12 -export -out ca.pfx -inkey ca.key -in ca.crt
pkcs12 -export -out client.pfx -inkey client.key -in client.crt
which will create p12(.pfx) file for each certificate. Then used them into your code like below .
see below lonk for more information
maybe this link also help you .
Good luck
CodePudding user response:
Based on the previous suggestions your code should look like this:
var ftpServer = "ftp://xxx.yyy.zz/";
var ftpUsername = "aaaaa";
var ftpPassword = "bbbbb";
var downloadedFilePath = "c:\\temp\\";
var downloadedFileName = "file.xls";
var certName = "MyCertName" //Use yours
var password = "MyCertPassword"; //Use yours
FtpWebRequest request = null;
ServicePointManager.SecurityProtocol = ServicePointManager.SecurityProtocol | SecurityProtocolType.Tls12;
ServicePointManager.ServerCertificateValidationCallback = delegate (object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) {
return true;
};
//Load certificates (one or more)
X509Certificate2Collection certificates = new X509Certificate2Collection();
certificates.Import(certName, password, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
// Get the object used to communicate with the server.
request = (FtpWebRequest)WebRequest.Create(ftpServer "file_on_ftp_server.xls");
// download the file
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.Credentials = new NetworkCredential(ftpUsername, ftpPassword);
request.ClientCertificates = certificates; //Use certificates
request.EnableSsl = true;
request.KeepAlive = false;
FtpWebResponse response = (FtpWebResponse)request.GetResponse(); // <--- ERROR
Stream responseStream = response.GetResponseStream();
FileStream writer = new FileStream(downloadedFilePath downloadedFileName, FileMode.Create);
Note: I have not tested the solution because I don't have an environment to test it on