sshnet / SSH.NET

SSH.NET is a Secure Shell (SSH) library for .NET, optimized for parallelism.
http://sshnet.github.io/SSH.NET/
MIT License
4.03k stars 937 forks source link

Add support for FIPS #190

Open gargml opened 7 years ago

gargml commented 7 years ago

Hi There, FIPS is the U.S. government standard of security for cryptography.

No place in this project have indication whether or not it support FIPS for communication with target devices.

will it be possible to add such support ? Please advise

Many thanks ! Gargml

darkoperator commented 7 years ago

FIPs as a standard only defines a certain set of algorithms that can be used. If enabled on a modern system it will downgrade the security since the standard references old algorithms proven to be vulnerable. In fact Enabling FIPS via GPO on windows breaks a lot of stuff in .Net like AES and SHA256. Why support this? https://blogs.technet.microsoft.com/secguide/2014/04/07/why-were-not-recommending-fips-mode-anymore/ https://technet.microsoft.com/en-us/library/cc750357.aspx

If you are referring for the library to be FIPS certified .. that is a lot of money and work. do not know if @drieseng wants to spend the money and time for that.

vidyasesh22 commented 7 years ago

I am using SSH.Net version 2016.0.0 and I'm getting the following error when trying to connect to SFTP server Failed to connect to server. Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidOperationException: This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms. at System.Security.Cryptography.MD5CryptoServiceProvider..ctor()

Does the SSH.Net version 2016.0.0 support FIPS ? is there a work around for this issue?

darkoperator commented 7 years ago

No because FIPS in windows eliminates most modern crypto algorithms making connections insecure so when enabled it cripples .Net crypto APIs used by SSH.Net

Sent from my iPhone

On May 8, 2017, at 12:08 PM, vidyasesh22 notifications@github.com wrote:

I am using SSH.Net version 2016.0.0 and I'm getting the following error when trying to connect to SFTP server Failed to connect to server. Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidOperationException: This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms. at System.Security.Cryptography.MD5CryptoServiceProvider..ctor()

Does the SSH.Net version 2016.0.0 support FIPS ? is there a work around for this issue?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

cocowalla commented 7 years ago

@darkoperator as much as I agree about the pointlessness of FIPS-mode nowadays, there are, regrettably, plenty organisations that demand it (especially in the defense sector).

Therefore I think it makes sense to use the FIPS-compliant version of algorithms wherever possible - for example, use the FIPS-compliant SHA256CryptoServiceProvider rather than SHA256Managed.

Having said all that, @vidyasesh22, if you have FIPS-mode enabled then you cannot use any implementation of MD5, as MD5 is not a valid FIPS algorithm. Actually, given how broken it is, you really shouldn't be using it at all these days, let alone in a FIPS environment.

darinkes commented 7 years ago

Then these organisations should pay for this pointless feature :)

mauroa commented 7 years ago

Is there any chance of allowing to define which encryption algorithm to use when instantiating things like PrivateKeyFile and PrivateKeyAuthenticationMethod? It's using MD5 as default, which is not FIPS compliant. I strongly agree that this degrades the performance of the encryption, but maybe letting the library consumers to decide it could get rid the issues that the users with FIPS enables are having.

27kartik commented 6 years ago

I am trying to use RenciSSH.Net for making a SSH connection to a machine/controller. When FIPS is disabled on that machine/controller, I am able to make the connection successfully. However when FIPS is enabled I get an error like "An established connection was aborted by the software in your host machine"

exec = new SshClient(controller.Address.ToString(), port, userid, password); exec.ConnectionInfo.Timeout = new TimeSpan(0, 0, 0, 0, timeoutms); exec.Connect();

Let me know if you need any information related to this problem. Also, when can we expect the support for FIPS in RenciSsh.Net ?

mclouden commented 6 years ago

"Then these organisations should pay for this pointless feature :)"

From someone at one of those organizations: While I wouldnt even know who to ask to pay for such a feature, what follows is how we modified the project code (minimal) to make it work. Liking or not liking FIPs is not a question - in healthcare everything is supposed to be hardened servers, which means we must live with this. If the changes make sense, and are not impactful to behavior on the wider range of platforms supported by ssh.net, I hope that we will see this support in the official package at some time in the future.

I can just as easily provide the local changes back, assuming I can work out the process.

Assumption: Build setting 'FIPS'

ConnectionInfo constructor:

HmacAlgorithms = new Dictionary<string, HashInfo> {

if !FIPS

            {"hmac-md5", new HashInfo(16*8, CryptoAbstraction.CreateHMACMD5)},
            {"hmac-md5-96", new HashInfo(16*8, key => CryptoAbstraction.CreateHMACMD5(key, 96))},

endif

            {"hmac-sha1", new HashInfo(20*8, CryptoAbstraction.CreateHMACSHA1)},

....

CryptoAbstractions:

// CreateMD5 is used in privatekey code. Changed return to base HashAlgorithm public static System.Security.Cryptography.HashAlgorithm CreateMD5() {

if FIPS

        return new System.Security.Cryptography.SHA1CryptoServiceProvider();

else

        return System.Security.Cryptography.MD5.Create();

endif

    }

// Note that thru testing, the basic SHA1.Create will always used Managed, which is not correct. Instead // explicitly create a new SHA1CSP instance (same pattern follows in remaining changes)

        public static System.Security.Cryptography.SHA1 CreateSHA1()
    {

if FEATURE_HASH_SHA1_CREATE

if FIPS

        return new System.Security.Cryptography.SHA1CryptoServiceProvider();

else

        return System.Security.Cryptography.SHA1.Create();

endif

elif FEATURE_HASH_SHA1_MANAGED

        return new System.Security.Cryptography.SHA1Managed();

endif

    }

// This is where things get wierd: You would think that SHA256CSP.Create would do what you want // It doesnt. It creates Managed. Must explicitly new a SHA256CSP instance public static System.Security.Cryptography.SHA256 CreateSHA256() {

if FEATURE_HASH_SHA256_CREATE

if FIPS

        return new System.Security.Cryptography.SHA256CryptoServiceProvider();

else

        return System.Security.Cryptography.SHA256CryptoServiceProvider.Create();

endif

elif FEATURE_HASH_SHA256_MANAGED

        return new System.Security.Cryptography.SHA256Managed();

endif

    }

    public static System.Security.Cryptography.SHA384 CreateSHA384()
    {

if FEATURE_HASH_SHA384_CREATE

if FIPS

        return new System.Security.Cryptography.SHA384CryptoServiceProvider();

else

        return System.Security.Cryptography.SHA384.Create();

endif

elif FEATURE_HASH_SHA384_MANAGED

        return new System.Security.Cryptography.SHA384Managed();

endif

    }

    public static System.Security.Cryptography.SHA512 CreateSHA512()
    {

if FEATURE_HASH_SHA512_CREATE

if FIPS

        return new System.Security.Cryptography.SHA512CryptoServiceProvider();

else

        return System.Security.Cryptography.SHA512.Create();

endif

elif FEATURE_HASH_SHA512_MANAGED

        return new System.Security.Cryptography.SHA512Managed();

endif

    }
darkoperator commented 6 years ago

Not even DOD STIG has FIPS Because it actually downgrades the security of the encryption on the box

Sent from my iPhone

On Feb 21, 2018, at 9:19 AM, mclouden notifications@github.com wrote:

"Then these organisations should pay for this pointless feature :)"

From someone at one of those organizations: While I wouldnt even know who to ask to pay for such a feature, what follows is how we modified the project code (minimal) to make it work. Liking or not liking FIPs is not a question - in healthcare everything is supposed to be hardened servers, which means we must live with this. If the changes make sense, and are not impactful to behavior on the wider range of platforms supported by ssh.net, I hope that we will see this support in the official package at some time in the future.

I can just as easily provide the local changes back, assuming I can work out the process.

Assumption: Build setting 'FIPS'

ConnectionInfo constructor:

HmacAlgorithms = new Dictionary<string, HashInfo> {

if !FIPS

{"hmac-md5", new HashInfo(168, CryptoAbstraction.CreateHMACMD5)}, {"hmac-md5-96", new HashInfo(168, key => CryptoAbstraction.CreateHMACMD5(key, 96))},

endif

{"hmac-sha1", new HashInfo(20*8, CryptoAbstraction.CreateHMACSHA1)}, ....

CryptoAbstractions:

// CreateMD5 is used in privatekey code. Changed return to base HashAlgorithm public static System.Security.Cryptography.HashAlgorithm CreateMD5() {

if FIPS

return new System.Security.Cryptography.SHA1CryptoServiceProvider();

else

return System.Security.Cryptography.MD5.Create();

endif

}

// Note that thru testing, the basic SHA1.Create will always used Managed, which is not correct. Instead // explicitly create a new SHA1CSP instance (same pattern follows in remaining changes)

    public static System.Security.Cryptography.SHA1 CreateSHA1()
{

if FEATURE_HASH_SHA1_CREATE

if FIPS

return new System.Security.Cryptography.SHA1CryptoServiceProvider();

else

return System.Security.Cryptography.SHA1.Create();

endif

elif FEATURE_HASH_SHA1_MANAGED

return new System.Security.Cryptography.SHA1Managed();

endif

}

// This is where things get wierd: You would think that SHA256CSP.Create would do what you want // It doesnt. It creates Managed. Must explicitly new a SHA256CSP instance public static System.Security.Cryptography.SHA256 CreateSHA256() {

if FEATURE_HASH_SHA256_CREATE

if FIPS

return new System.Security.Cryptography.SHA256CryptoServiceProvider();

else

return System.Security.Cryptography.SHA256CryptoServiceProvider.Create();

endif

elif FEATURE_HASH_SHA256_MANAGED

return new System.Security.Cryptography.SHA256Managed();

endif

}

public static System.Security.Cryptography.SHA384 CreateSHA384()
{

if FEATURE_HASH_SHA384_CREATE

if FIPS

return new System.Security.Cryptography.SHA384CryptoServiceProvider();

else

return System.Security.Cryptography.SHA384.Create();

endif

elif FEATURE_HASH_SHA384_MANAGED

return new System.Security.Cryptography.SHA384Managed();

endif

}

public static System.Security.Cryptography.SHA512 CreateSHA512()
{

if FEATURE_HASH_SHA512_CREATE

if FIPS

return new System.Security.Cryptography.SHA512CryptoServiceProvider();

else

return System.Security.Cryptography.SHA512.Create();

endif

elif FEATURE_HASH_SHA512_MANAGED

return new System.Security.Cryptography.SHA512Managed();

endif

}

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

mclouden commented 6 years ago

i dont expect it makes any sense. Unfortunately TriCare does. As do the various health exchanges

Kim-SSi commented 6 years ago

I also have the same problem at some sites. FIPS mode is enabled in Windows and therefore .NET. I would find it useful to be able to have one build that would allow altering the FIPS usage at runtime. This would allow greater SSH server support from a singe build.

This could all be changed to make the FIPS define a variable. That might be a better approach. Or better yet detect it at runtime. Checking if MD5 works might be the best way. Don’t use it if is doesn’t work.

Maybe a cached version of:

public bool FIPSIsEnabled() { try { var sha1 = new SHA1Managed(); / var md5 = System.Security.Cryptography.MD5.Create(); / return false; } catch { // ignored } return true; }

What are your thoughts? Regards, Kim

dudeinco commented 6 years ago

We had the same issue, and I have verified that version 2013.4.7.0 is FIPS compliant.

Poonaka commented 6 years ago

To get around the FIPS error you can disable the .NET algorithm check/exceptions. We added the following to our app.config:

`

`

See https://blogs.msdn.microsoft.com/shawnfa/2008/03/14/disabling-the-fips-algorithm-check/

grannypron commented 5 years ago

To get around the FIPS error you can disable the .NET algorithm check/exceptions. We added the following to our app.config:

<configuration> <runtime> <enforceFIPSPolicy enabled="false"/> </runtime> </configuration>

See https://blogs.msdn.microsoft.com/shawnfa/2008/03/14/disabling-the-fips-algorithm-check/

Worked. Thx & much love.

A9G-Data-Droid commented 3 years ago

DoD STIGs do require FIPS mode: https://www.stigviewer.com/stig/windows_10/2017-04-28/finding/V-63811

The FIPS standard evolves with time. FIPS 140-3 is the "modern" version: https://en.wikipedia.org/wiki/FIPS_140-3

SSH is a great example of a place where disabling FIPS algorithm checks would be a compliance violation. Do not disable these checks as a work-around in a controlled environment.

The solution provided by @mclouden is correct.

jackchi29 commented 3 years ago

In public safety industry, FIPS compliant is critical.
Thanks @mclouden to provide a solution and @iamkrillin to create the Pull Request #806 based on it. Hope the solution will get reviewed and merged soon. Thanks!

petcua1 commented 2 years ago

Really useful #806 for customers that require FIPS. Can this PR be merged?

lifeincha0s commented 2 years ago

It is the responsibility of the server to enforce FIPS, not the client. The client library is a generalized application that is intended to connect to a very broad set of remote server types. The server determines the protocols required for connections. If you refer to the DISA STIGs, as DoD-types like to do, you will notice that none of the checks talk about locking down client SSH applications. The name says how they should be implemented, Security Technical Implementation Guide. They are meant as a guide for how to lock down a system. Blindly applying the STIGs will break system functionality. The FIPS compliance that Microsoft enforces is a bad implementation since it was hand-jammed into .NET without regard for existing security mechanisms.

A9G-Data-Droid commented 2 years ago

@lifeincha0s If the server enforces it, the client must support it or the connection will fail. This is seen in #190 and #276.

Once PR #806 is merged all these issues can be closed.

A9G-Data-Droid commented 1 year ago

I can confirm that version 2023.0.0 can be run on a FIPS compliant system.

This issue can be closed.

WojciechNagorski commented 1 year ago

@A9G-Data-Droid Great! Big thanks for this information!