Archived Forum Post

Index of archived forum posts

Question:

FTPS/Client Certificate not working. Native C#/FtpWebRequest works

Mar 24 '15 at 12:06

I have a problem using FTP2 component to connect to a FTPS server using a client certificate.

Using Chilkat 9.5.0.48 / x64 on Windows Server 2008 r2 thru Powershell 3.0

$script:ftp = New-Object Chilkat.Ftp2 $success = $ftp.UnlockComponent("xxx")

$ftp.verboselogging = 1

$ftp.Hostname = "xxxxx" $ftp.Port = 6371 $ftp.Username = "anonymous" $ftp.Password = "anonymous" $ftp.Passive = $true

# This example will use explict TLS/SSL. # Establish an explicit secure channel after connection # on the standard FTP port 21. $ftp.AuthTls = $true

# The Ssl property is for establishing an implicit SSL connection # on port 990. Because this example uses explicit SSL, it # should remain $false. $ftp.Ssl = $false

# Load a certificate from Local Machine store $ccs = New-Object ChilKat.CertStore $certStore = $ccs.OpenLocalSystemStore($true)

# Skatteministeriet - DMR $cert = $ccs.FindCertBySubject("FORSIKRINGS-AKTIESELSKABET ALKA - NemID Test") #$cert = $ccs.FindCertBySubject($certificate)

# Use this certificate for our secure (SSL/TLS) connection: $ftp.SetSslClientCert($cert)

# Connect and login to the FTP server. The connection is # made secure because of the AuthTls setting. $success = $ftp.Connect() if ($success -ne $true) { throw "Det er ikke lykkedes at oprette forbindelse til DMR: $($ftp.LastErrorText)" } else { $($ftp.LastErrorText) }

$ftp.Disconnect()

Error from LastErrorText.

        buildClientKeyExchange:
          buildClientKeyExchangeRsa:
            modulus_bitlen: 2048
            littleEndian: 1
            padding: PKCS 1.5
          --buildClientKeyExchangeRsa
        --buildClientKeyExchange
        getPrivateKey:
          certGetPrivateKeyAsDER:
            Checking via Crypto API for a private key...
          --certGetPrivateKeyAsDER
          Unable to export the private key.
        --getPrivateKey
        sendCertificateVerify:
          Sending ClientCertVerify message...
          msRsaSignHash:
            cert_def_provider: Microsoft Enhanced RSA and AES Cryptographic Provider
            acquireCSP:
              providerName: Microsoft Enhanced RSA and AES Cryptographic Provider
              keyContainer: FORSIKRINGS-AKTIESELSKABET ALKA - NemID Test
              verifyContext: 0
              machineKeyset: 0
              providerType: 0x18
              Success
            --acquireCSP
            **Failed to CryptSignHash
          --msRsaSignHash
          Failed to RSA sign via MS Crypto API.
        --sendCertificateVerify
        Failed to send client certificate verify message.
      --clientHandshake2
    --clientHandshake
    Client handshake failed. (1)
    connectionClosed: 0
  --convertToTls
  Failed to convert channel to SSL/TLS
--authTls
Failed to connect to FTP server.
Failed.**

I have made a small test-program with this native C# / .NET code and it just works. :-|

            FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://xxx:6371");

            // Query certificate from store
            X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
            store.Open(OpenFlags.ReadOnly);
            const string tp = "4FF5645341270EA321D5741193634886B82B8353";
            X509Certificate2 cert2 =
                store.Certificates.Find(X509FindType.FindByThumbprint, tp, true)[0];
            store.Close();

            request.Credentials = new NetworkCredential("anonymous", "anonymous");
            request.Method = WebRequestMethods.Ftp.UploadFile;
            request.UseBinary = true;
            request.UsePassive = true;
            request.EnableSsl = true;
            // Add certificate into request
            request.ClientCertificates.Add(cert2);
            request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;

            FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            Stream responseStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(responseStream);
            Console.WriteLine(reader.ReadToEnd());

            reader.Close();
            response.Close();

Answer

I was not able to reproduce the problem. Please try this latest build:

32-bit Download: http://www.chilkatsoft.com/download/preRelease/ChilkatDotNet4-9.5.0-win32.zip
64-bit Download: http://www.chilkatsoft.com/download/preRelease/ChilkatDotNet4-9.5.0-x64.zip

Here is the relevant part of the LastErrorText when I test (which shows success)

      msRsaSignHash:
        cert_def_provider: Microsoft Enhanced RSA and AES Cryptographic Provider
        acquireCSP:
          providerName: Microsoft Enhanced RSA and AES Cryptographic Provider
          keyContainer: 2e370ac0-85dd-4daa-82e1-ce7241d4e7e7
          verifyContext: 0
          machineKeyset: 0
          providerType: 0x18
          Success
        --acquireCSP
        cryptSigSize: 128
      --msRsaSignHash