TL;DR: Either your first (FTPS) or third (SFTP) options are sound choices. There are some minor security differences between them, depending on things like whether you know the server D's public key for SFTP or whether you can use public key authentication (or TLS mutual authentication) instead of the slightly weaker password authentication, but either approach is quite adequate. There are lots of ways to do this, but either of those are probably the best bets for this situation.
Use ftp_ssl_connect(), which however fails with the error : PHP Warning: ftp_login(): Server not configured for encryption.
That just sounds like you haven't actually configured SSL/TLS on your FTP server... or at least, you haven't configured it the way PHP (Why, of all things, PHP?!?) expects. The original FTP specification doesn't support secure connections at all, and there are a few different ways to retrofit it into the protocol (sometimes called FTPS, by analogy to HTTPS and very distinct from SFTP which is a completely different protocol over SSH instead of SSL/TLS). Obviously, make sure the FTP server on D is configured with a trusted certificate, but if you have such a certificate plus some method of client authentication (probably username+password, since it's FTP), that should work fine.
Use symmetric encryption + asymmetric encryption of the symmetric key (mainly to reach unlimited message length in terms of encryption, which is not possible with asymmetric encryption as far as I know). This however seems like overshooting x100000 to me; and encrypting and decrypting a csv - file holding thousands of rows may not be really performant.
As schroeder's comment says, you just described the core of SSL/TLS and also SSH (used for SFTP), at least when doing RSA key exchange ([EC]DHE key exchanges - favored because they provide forward secrecy - are slightly more complicated). You also described OpenPGP while you're at it.
You absolutely should not try to re-invent those protocols - they are complicated, tricky beasts, and lots of mistakes have been made in both protocol design and in implementations, even by people much more experienced than you or I - but you have the basic idea right. Your biggest error here (beyond not realizing that you're reinventing the wheel without considering important questions like public key distribution) is thinking that it's going to be some kind of performance disaster. That exact type of process happens every time you load a web page over HTTPS, or fetch your email over IMAP4 + STARTTLS, or SFTP a file, or... you get the idea. You're not going to avoid that performance impact, but it's also way smaller than you seem to think it is.
If you did want to go this route (encrypting the file before transmitting it over an insecure network protocol such as plain FTP), you could use something conforming to OpenPGP, such as GnuPG (commonly gpg
). I don't recommend it though; lots of complexity for no point.
Use the PHP extension phpseclib to transfer the file across an SFTP connection.
If you have an SFTP server on server D, this might be the simplest option. Do make sure you know its public key, though, and that it's being verified. SSH (which SFTP uses for security) is generally trust-on-first-use and remembers the key the first time you use it, but that requires not being subject to a MitM attack at first use. Consider using public key authentication rather than username+password authentication if you can.
Just for completion, a few other options:
Have an HTTPS web server on D, configured to accept authenticated file uploads, and upload the file as/in the body of an authenticated HTTPS POST or PUT request. There's really no point setting this up if you don't already have an HTTPS server on D with an upload endpoint that is easy to interact with programmatically (i.e. it doesn't require a separate login step that provides a cookie), but it would work fine.
Establish an SSH connection for port forwarding to the FTP port(s) on D, and then FTP your file to the locally forwarded port on localhost. It will look like you're FTPing it over an insecure connection to a local FTP server, but actually you're sending it over a secure connection to the FTP server on D (this is called FTP over SSH). This is strictly more complicated than just using SFTP though, so don't.
Invoke a subprocess (sftp
or ftp
or curl
or whatever) to transfer the file using a tool that's actually built for this, instead of using a web application framework originally designed for serving personal home pages. Of course, if you're doing this, you probably wouldn't want to be using PHP for the cronjob at all (still confused why you are; a simple shell script invoking the MariaDB command line client and one of the tools above would probably work fine?). The main danger with using subprocesses here is making sure that there's no risk of command injection (or shell injection if for some reason you use a shell) due to e.g. improperly escaped malicious file names. That shouldn't be a problem, since you control the file name. On the other hand, it probably buys you nothing over just using PHP modules.
ftp_login()
, got an error that you didn't understand, and instead of resolving the error, you want to look at a wide range of different options for secure file transfer from first principles. What if you just configured server D to resolve the error?