0 votes
by (120 points)

Hi. I’m using rebex ftp and having an issue with ssl. The initial handshake negotiates TLS 1.2 ecdhe_rsa AES 128 gem. However when login called the ftp server rejects. Exception caught is SSL Strength Insufficient. SSL certificate is valid and accepted. Only way I can find to stop this issue is to explicitly set the TLS cipher suite to DHE_RSA_WITH_AES_256_GCM_SHA384. Can you shed any light why the negotiation selects a cipher that is then rejected. Thanks

Applies to: Rebex FTP/SSL

2 Answers

0 votes
by (144k points)

In TLS/SSL protocol, the client announces a list of supported ciphers to the server, and the server is supposed to pick one that it considers acceptable.

These are two likely explanations for the issue you encountered:

a) Rebex FTP client did not announce support for any cipher that the server would consider sufficient. Therefore, the server only accepted the connection to be able to inform the client about the problem. (This could easily occur with .NET Compact Framework edition of Rebex FTP, where DHE_ ciphers are disabled by default.)

b) Rebex FTP client did announce support for ciphers that the server would consider sufficient. However, instead of selecting one of them, the server negotiated another cipher. (In this case, you would have to ask the server vendor or administrator about why they negotiate a cipher they later reject instead of a more suitable one.)

If you would like to determine whether any of these possible explanation applies to your scenario, please create a communication log using Ftp object's LogWriter property and see which suites were actually announced (in 'Applicable cipher suites' log entry). If you prefer, post the log here or mail it to support@rebex.net for analysis.

(If the issue persists even when you assign TlsCipherSuite.Secure to Ftp.Settings.SslAllowedSuites, that would suggest explanation (b)).

0 votes
by (240 points)

I have just ran across this exact same issue, and I have discovered the problem and how to solve it.

With SSL/TLS, the list of supported ciphers should be returned in order of preference. The order is extremely important, as it will ensure the most secure connection that is possible between the client and the server. When the FTPS server sees the list of client supported ciphers, it starts at the top of the list and makes its way down. If the server itself supports the first cipher, then it will select it; if not, then it will move down the list to the next entry. This is why clients such as WS-FTP return all of the AES 256 ciphers first, then all of the AES 128 ciphers, then all of the weaker ciphers, thus ensuring that the strongest possible cipher is used.

Unfortunately, the default Rebex cipher order is a little strange, and it does not ensure the most secure connection possible. For some reason, the elliptical curve ciphers are being returned in pairs, with the AES 128 version listed first, then the AES 256 version listed second. This means that the AES 128 version will always be preferentially used above the AES 256 version. (The non-elliptical ciphers are also being returned in pairs, but at least those pairs are AES 256 first, then AES 128 second, so the problem isn't as readily seen there.)

Because your FTPS server supports elliptical ciphers, it sees the first cipher as being an AES 128 cipher. Your FTPS server probably only allows 256-bit ciphers. Since it assumes that the ciphers are listed in order of strength, it then assumes that all of the following ciphers are AES 128 or weaker, and so it returns the "FTPS SSL strength insufficient" error.

Fortunately, you can change the order of preference in Rebex, which should allow your connection to go through. The SetPreferredSuites() method allows you to set the preferred order of the ciphers. You can set the order of all of the ciphers; setting the order does not activate any ciphers, it merely ensures the order of all active ciphers. You can still use the SslAllowedSuites() method if you wish to manually determine which ciphers will be active; otherwise, whatever ciphers are normally present will be shown in order.

I have come up with a preferred cipher order list that works as of Rebex 2022 R6.6. In the future, ciphers may need to be added or removed from this list with new releases of Rebex. This list largely follows the general cipher order of WS-FTP, using the following priorities:

Priority 1: All AES 256 ciphers, then all AES 128 ciphers, then all remaining ciphers generally ordered by key size.
Priority 2: ECDHE, then DHE, then RSA, then DH_anon.
Priority 3: SHA384, then SHA256, then SHA.
Priority 4: For ECDHE ciphers: RSA, then ECDSA. For DHE ciphers: RSA, then DSS.

// The below TLS Cipher Suites are for TLS 1.1 and TLS 1.2 only, as of Rebex 2022 R6.6
TlsCipherSuite[] tlsCipherSuiteOrder = new TlsCipherSuite[] {
    TlsCipherSuite.ECDHE_RSA_WITH_AES_256_GCM_SHA384,
    TlsCipherSuite.ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
    TlsCipherSuite.ECDHE_RSA_WITH_AES_256_CBC_SHA384,
    TlsCipherSuite.ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
    TlsCipherSuite.ECDHE_RSA_WITH_AES_256_CBC_SHA,
    TlsCipherSuite.ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
    TlsCipherSuite.DHE_RSA_WITH_AES_256_GCM_SHA384,
    TlsCipherSuite.DHE_DSS_WITH_AES_256_GCM_SHA384,
    TlsCipherSuite.DHE_RSA_WITH_AES_256_CBC_SHA256,
    TlsCipherSuite.DHE_DSS_WITH_AES_256_CBC_SHA256,
    TlsCipherSuite.DHE_RSA_WITH_AES_256_CBC_SHA,
    TlsCipherSuite.DHE_DSS_WITH_AES_256_CBC_SHA,
    TlsCipherSuite.RSA_WITH_AES_256_GCM_SHA384,
    TlsCipherSuite.RSA_WITH_AES_256_CBC_SHA256,
    TlsCipherSuite.RSA_WITH_AES_256_CBC_SHA,
    TlsCipherSuite.DH_anon_WITH_AES_256_CBC_SHA256,
    TlsCipherSuite.DH_anon_WITH_AES_256_CBC_SHA,
    TlsCipherSuite.ECDHE_RSA_WITH_AES_128_GCM_SHA256,
    TlsCipherSuite.ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
    TlsCipherSuite.ECDHE_RSA_WITH_AES_128_CBC_SHA256,
    TlsCipherSuite.ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
    TlsCipherSuite.ECDHE_RSA_WITH_AES_128_CBC_SHA,
    TlsCipherSuite.ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
    TlsCipherSuite.DHE_RSA_WITH_AES_128_GCM_SHA256,
    TlsCipherSuite.DHE_DSS_WITH_AES_128_GCM_SHA256,
    TlsCipherSuite.DHE_RSA_WITH_AES_128_CBC_SHA256,
    TlsCipherSuite.DHE_DSS_WITH_AES_128_CBC_SHA256,
    TlsCipherSuite.DHE_RSA_WITH_AES_128_CBC_SHA,
    TlsCipherSuite.DHE_DSS_WITH_AES_128_CBC_SHA,
    TlsCipherSuite.RSA_WITH_AES_128_GCM_SHA256,
    TlsCipherSuite.RSA_WITH_AES_128_CBC_SHA256,
    TlsCipherSuite.RSA_WITH_AES_128_CBC_SHA,
    TlsCipherSuite.DH_anon_WITH_AES_128_CBC_SHA256,
    TlsCipherSuite.DH_anon_WITH_AES_128_CBC_SHA,
    TlsCipherSuite.ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
    TlsCipherSuite.ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
    TlsCipherSuite.ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
    TlsCipherSuite.ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
    TlsCipherSuite.ECDHE_RSA_WITH_RC4_128_SHA,
    TlsCipherSuite.ECDHE_ECDSA_WITH_RC4_128_SHA,
    TlsCipherSuite.DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
    TlsCipherSuite.DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
    TlsCipherSuite.DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
    TlsCipherSuite.DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA,
    TlsCipherSuite.DHE_DSS_EXPORT1024_WITH_RC4_56_SHA,
    TlsCipherSuite.DHE_RSA_WITH_3DES_EDE_CBC_SHA,
    TlsCipherSuite.DHE_DSS_WITH_3DES_EDE_CBC_SHA,
    TlsCipherSuite.DHE_DSS_WITH_RC4_128_SHA,
    TlsCipherSuite.DHE_RSA_WITH_DES_CBC_SHA,
    TlsCipherSuite.DHE_DSS_WITH_DES_CBC_SHA,
    TlsCipherSuite.RSA_WITH_3DES_EDE_CBC_SHA,
    TlsCipherSuite.RSA_WITH_RC4_128_SHA,
    TlsCipherSuite.RSA_WITH_RC4_128_MD5,
    TlsCipherSuite.RSA_WITH_DES_CBC_SHA,
    TlsCipherSuite.RSA_EXPORT1024_WITH_DES_CBC_SHA,
    TlsCipherSuite.RSA_EXPORT1024_WITH_RC4_56_SHA,
    TlsCipherSuite.RSA_EXPORT_WITH_DES40_CBC_SHA,
    TlsCipherSuite.RSA_EXPORT_WITH_RC2_CBC_40_MD5,
    TlsCipherSuite.RSA_EXPORT_WITH_RC4_40_MD5,
    TlsCipherSuite.DH_anon_WITH_3DES_EDE_CBC_SHA,
    TlsCipherSuite.DH_anon_WITH_DES_CBC_SHA,
    TlsCipherSuite.DH_anon_WITH_RC4_128_MD5
};
_ftpConnection.Settings.SetPreferredSuites(tlsCipherSuiteOrder);

I wish that this was the default cipher order in Rebex, so that the strongest ciphers would be used first, and so that problems like "SSL Strength Insufficient" wouldn't occur in the future. For now, I will keep using this cipher order for all of my FTPS connections, and I will have to check for any cipher additions and removals in future releases of Rebex.

by (144k points)
Hello, many thanks for taking the time for posting the results of your research! This could be useful to other users who run into the same issue.

We are open to tweaking the default cipher in R7 or R8 releases. However, we'll have to carefully consider this first. For example, should we really prefer 256-bit AES/CBC to 128-bit AES/GCM, or 256-bit AES with SHA-1 hash to 128-bit AES with SHA-256? That seems questionable. We'll also review common TLS clients and servers to see what's the current industry practice.

However, I would like to clarify the following statements:
"The order is extremely important"
"When the FTPS server sees the list of client supported ciphers, it starts at the top of the list and makes its way down. If the server itself supports the first cipher, then it will select it; if not, then it will move down the list to the next entry."

This is NOT how TLS is supposed to work. The TLS client is supposed to list the ciphers in the order of preference, but the TLS server is quite free to choose any of these ciphers - it does not have to pick the first one. From RFC 5246 (https://www.rfc-editor.org/rfc/rfc5246#page-40):
"The server will select a cipher suite or, if no acceptable choices are presented, return a handshake failure alert and close the connection."

This means that the TLS server is free to choose any cipher from the list. The server is supposed to simply ignore ciphers it deems insufficient or undesirable, and almost all contemporary servers actually do this (they pick SHA-2 instead of SHA-1 or MD5, despite the client's order of preference).

Of course, the wording of the specification does make it possible for the server to pick a cipher according to the client's preference. But if a specific server closes the connection when it encounters a known-but-prohibited cipher listed before a known-and-allowed cipher, that would seem to be a server-side bug rather than a feature. This is not normal TLS server behavior.
by (240 points)
Thank you for your response!  I agree with you, the problem is really more of a server-side bug.  Ideally, the server should exhaust all possibilities before returning the SSL Strength Insufficient error.

I based my cipher order on WS-FTP Client, since it happened to be the client that was installed at the location where I was testing.  I just now realized, however, that the server itself was WS-FTP Server 8.6.0.  So perhaps the server was written with an unknown bias towards the cipher order that they programmed in their own client.

In any case, I have been using Rebex for well over 10 years, and this was the first time that I had run across this issue, so hopefully it's not a very common problem for others.  I have really enjoyed the Rebex product.  Thank you for the good work!
by (144k points)
Thanks!
We will update the default TLS cipher order in R7.0 in early 2023. We will make the new order similar to that of common contemporary third-party software, so hopefully even servers with somewhat questionable behavior will be fine with it.
...