I'm not quite sure what "common shared key" means, but FTP over TLS/SSL supports authentication using a client certificate that includes a public key and is associated with a private key that is kept secret by the client (it's not shared). Is this what you need?
In that case, if the client has already authenticated using a certificate when connecting to the FTP server, there are three possibilities on what the server requires next:
- The server still requires a valid username and password.
- The server requires the client to specify username and password, but accepts any values (Microsoft IIS FTP is an example of such server).
- The server does not require a username and password (Tumbleweed server is an example of this server).
In your case, either (2) or (3) seems to apply, which means the following code should get the client authenticated:
// load the client certificate with a private key
Certificate clientCert = Certificate.LoadDerWithKey("client.cer", "client.pri", "password");
// alternatively, load the client certificate from a PFX/P12 file
// Certificate clientCert = Certificate.LoadPfx("client.p12", "password");
// build a full certificate chain from the client certificate
CertificateChain clientChain = CertificateChain.BuildFrom(clientCert);
// create an Ftp object
using (var ftp = new Ftp())
{
// set up client certificate request handler
ftp.Settings.SslClientCertificateRequestHandler = CertificateRequestHandler.CreateRequestHandler(clientChain);
// connect to the server using explicit TLS/SSL mode
ftp.Connect("server01", 21, SslMode.Explicit);
// perform dummy authentication if needed
if (!ftp.IsAuthenticated)
ftp.Login("anyuser", "anypassword");
// transfer some files
...
// disconnect gracefully
ftp.Disconnect();
}
Instead of loading a certificate from a P12/PFX file or a CER/PRI pair, it's possible to use a certificate from Windows certificate store as well.
(Also, please note that many public FTP servers allow read-only password-less access through "anonymous" user name and "guest" password - see RFC 1635 for details. However, this most likely doesn't apply in your scenario.)