4

I have to send PGP encrypted file in asc format to FTP folder via sFTP. Is there a way to PGP encrypt a stream (which is CSV formatted stream) and push it to the sFTP without having to save it on local machine.

Below is the function I use for PGP encryption which takes file name as param:

Private Function PGPEncrypt(ByVal FileName As String) As Boolean
        Dim errorHappened As Boolean = False
        Dim encodedFileName As String = String.Format("{0}{1}", FileName, ".asc")
        Dim pgpRecipient As String = System.Configuration.ConfigurationManager.AppSettings.Get("PgpRecipient")
        Dim psi As System.Diagnostics.ProcessStartInfo
        Dim ErrorResult As String = ""
        Dim Result As String = ""
        Try
            psi = New ProcessStartInfo(System.Configuration.ConfigurationManager.AppSettings.Get("PgpPath"))
            psi.CreateNoWindow = True
            psi.UseShellExecute = False
            psi.Arguments = String.Format(" --armor --yes --recipient ""{0}"" --output ""{1}"" --encrypt ""{2}""", _
                                          pgpRecipient, encodedFileName, FileName)
            psi.RedirectStandardInput = True
            psi.RedirectStandardOutput = True
            psi.RedirectStandardError = True
            ProcessPGP = System.Diagnostics.Process.Start(psi)
            ProcessPGP.StandardInput.Write(m_Passphrase)
            Result = ProcessPGP.StandardError.ReadToEnd()
            ProcessPGP.WaitForExit()
        Catch ex As Exception
            errorHappened = True
            Dim ReadError As New StringBuilder()
            ReadError.Append(vbCrLf & "Error Detail:")
            ReadError.Append(vbCrLf & ex.ToString())
            OurEventLog.WriteEntry(ReadError.ToString(), EventLogEntryType.Error)
        End Try
        Return errorHappened
    End Function

Again, the main requirement is not to save the PGP encrypted file locally and then send to FTP but PGP encrypted file must be created through a stream.

Any ideas?

UPDATE:

FTP Code:

 ftp.ConnectMode = FTPConnectMode.PASV
                ftp.RemoteHost = Csla.ConfigurationManager.AppSettings("FTPRemoteHost")
                If _blnDiagnostics Then DiagnosticsManager.Publish("STREAM_TO_FTP: CONNECT TO FTP", DiagnosticsManager.EntryType.SuccessAudit)
                ftp.Connect()
                ftp.Login(strUser, strPassword)
                ftp.TransferType = FTPTransferType.BINARY 'ASCII
                ftp.Put(OUTBOUNDMESSAGE, pFilename)

                ftp.Quit()
                ftp = Nothing

OUTBOUNDMESSAGE is the System.IO.Stream.

Learner
  • 3,904
  • 6
  • 29
  • 44

1 Answers1

0

Instead of taking the filename as an option on the command line, you can pass - to --output which directly exposes the output to the console. You can stream this data directly.

Your Arguments property would then look like this:

psi.Arguments = String.Format(" --armor --yes --recipient ""{0}"" --output - --encrypt ""{1}""", _
                                      pgpRecipient, FileName)

When you execute the process, ProcessPGP.StandardOutput should yield the stream you need.

CassOnMars
  • 6,153
  • 2
  • 32
  • 47
  • What about FTP component? Just send this encrypted data stream to FTP and save it as asc? – Learner Mar 01 '13 at 15:49
  • Since you didn't include any code of how you're sending the data over FTP, I cannot say for sure what you would do. If you have to stream your existing file over FTP, then it is simply a matter of using the output stream instead. If it's a library that takes a file in as an argument and does the streaming work itself, then you'll need to find an FTP library that does support taking in some form of `Stream`. – CassOnMars Mar 01 '13 at 15:51
  • Added code for FTP. I use ftp.Put which takes stream as parameter. So, basically you mean PGP encrypt the stream and save it as asc on ftp? – Learner Mar 01 '13 at 15:58
  • You can use the `ProcessPGP.StandardOutput.BaseStream` property in place of the `OUTBOUNDMESSAGE` variable you have in your added code. – CassOnMars Mar 01 '13 at 16:03