使用VB.NET中的客户端证书使用FTPS上传文件

时间:2017-11-21 17:34:14

标签: .net vb.net ssl ftp ftps

我的任务是能够通过FTPS将文件发送到网站。这需要成为生成要发送的文件的进程的一部分。我得到了一个能够连接到网站的程序(CoreFTP),我可以看到/推送文件。我尝试使用System.Diagnostics.Process通过.Net示例程序将命令行用于CoreFTP,并将用户更改为导入证书的用户)但是没有工作(没有错误但没有文件)在服务器上),所以我回到尝试使用.NET库连接它。

我遇到的问题是,要连接到网站,我必须与AUTH TLS连接,并且需要使用具有特定证书的Windows TLS / SSL。

我发现这个例子(https://www.limilabs.com/blog/use-ssl-with-ftp-explicit)至少谈到了使用AuthTLS,但是当我把它放在我的项目中时,它说FTP是未定义的。我尝试了建议的修复程序,但它们最终被破坏了(包括一个库,然后它说我需要实现idisposable)。

我发现另一个网站(https://support.microsoft.com/en-us/help/901183/how-to-call-a-web-service-by-using-a-client-certificate-for-authentica)谈到获取特定证书,但我不确定如何在FTP上使用它。

所以,我对解决方案的偏好是: 1.不使用第三方库的.NET解决方案。 2.使用开源第三方库的.NET解决方案。 3. .NET解决方案,我可以使命令行工作以使用CoreFTP,其中我在与运行程序的用户不同的用户下运行命令行(导致证书/ CoreFTP配置文件是用户特定的)。 4.使用我需要支付的库的.NET解决方案(真的希望不建议这个)。

这是(或多或少)我用于通过.net程序中的命令行命令运行CoreFTP的代码:

appname = "D:\Programs\coreftp.exe"
args = " -s -O -site Server_QA -u \\machine\docs\test.txt -p / " +
       "-output \\machine\docs\corelog1.txt"
standOut = String.Empty
AddHandler objProcess.OutputDataReceived, AddressOf process_OutputDataReceived
' Start the Command and redirect the output
objProcess.StartInfo.UseShellExecute = False
objProcess.StartInfo.RedirectStandardOutput = True
objProcess.StartInfo.CreateNoWindow = True
objProcess.StartInfo.RedirectStandardError = True
objProcess.StartInfo.Domain = "mydomain"
objProcess.StartInfo.UserName = "administrator"
objProcess.StartInfo.Password = New System.Security.SecureString
For Each chr As Char In pwd.ToCharArray()
    objProcess.StartInfo.Password.AppendChar(chr)
Next
objProcess.StartInfo.FileName() = AppName
If args.Length > 0 Then
    objProcess.StartInfo.Arguments() = args
End If
objProcess.Start()
objProcess.BeginOutputReadLine()
objProcess.WaitForExit()  'Set to run for 20 minutes
If objProcess.HasExited() Then
    'strOutput = objProcess.StandardOutput.ReadToEnd()
    strOutput = standOut
    strError = objProcess.StandardError.ReadToEnd()
    If strOutput IsNot Nothing AndAlso strOutput.Length > 0 Then
        PersonalDetailLog(strOutput)
    End If
    If strError IsNot Nothing AndAlso strError.Length > 0 Then
        Throw New ApplicationException(strError)
    End If
Else
    PersonalDetailLog(
        "The " + AppName + " Process has exceeded the 20 minute time out " +
        "is is being closed")
    If objProcess.Responding Then
        objProcess.CloseMainWindow()
        If Not objProcess.HasExited() Then
            objProcess.Kill()
        End If
    Else
        objProcess.Kill()
    End If
    Throw New ApplicationException("" + AppName + " Process Time Limit Exceeded.")
End If

1 个答案:

答案 0 :(得分:0)

示例代码:

Dim request As FtpWebRequest = WebRequest.Create("ftp://ftp.example.com")

request.Credentials = New NetworkCredential("username", "")

' Query certificate from store
Dim store As X509Store = New X509Store(StoreName.My, StoreLocation.CurrentUser)
store.Open(OpenFlags.ReadOnly)
Const tp = "2b6f8ac51a85cbaf429474a55304313968667611"
Dim cert As X509Certificate2 =
    store.Certificates.Find(X509FindType.FindByThumbprint, tp, True)(0)
store.Close()

' Add certificate into request
request.ClientCertificates.Add(cert)
request.EnableSsl = True

' Upload
request.Method = WebRequestMethods.Ftp.UploadFile

Using fileStream As Stream = File.OpenRead("C:\local\path\file.zip"),
      ftpStream As Stream = request.GetRequestStream()
    fileStream.CopyTo(ftpStream)
End Using