Using SshClient on Linux under Wine throws System.Security.Cryptography.CryptographicException

Open
#1,828 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
48/100
Issue type
Feature
Clarity
Mostly clear
Activity status
Quiet
Tech stack
csharp
Domain
cryptography

Research direction

Start at KeyExchangeECCurve25519 and inspect how SshClient exposes ConnectionInfo.KeyExchangeAlgorithms. Review the BclImpl and BouncyCastleImpl selection shown in the issue, then determine how a caller could configure the implementation before connecting. Done means the configured BouncyCastle path can be selected for Wine without manually removing key-exchange algorithms.

Written by the indexing model from the issue text.

Description

SSH.NET Version: 2026.0.0
.NET Version: 10.0.11
Wine Version: 11.0

When trying to connect a SshClient from a Windows Application running under Wine, I get the following exception:

System.PlatformNotSupportedException: The specified curve 'Curve25519' or its parameters are not valid for this platform.
---> System.Security.Cryptography.CryptographicException: Unknown error (0x80090029)
at System.Security.Cryptography.CngKey.Create(CngAlgorithm algorithm, String keyName, CngKeyCreationParameters creationParameters)
at System.Security.Cryptography.CngAlgorithmCore.GetOrGenerateKey(Nullable`1 curve)
--- End of inner exception stack trace ---
at System.Security.Cryptography.CngAlgorithmCore.GetOrGenerateKey(Nullable`1 curve)
at System.Security.Cryptography.ECDiffieHellmanCng.GenerateKey(ECCurve curve)
at Renci.SshNet.Security.KeyExchangeECCurve25519.BclImpl.GenerateClientPublicKey()
at Renci.SshNet.Security.KeyExchangeECCurve25519.StartImpl()
at Renci.SshNet.Security.KeyExchangeECCurve25519.Start(Session session, KeyExchangeInitMessage message, Boolean sendClientInitMessage)
at Renci.SshNet.Session.OnKeyExchangeInitReceived(KeyExchangeInitMessage message)
at Renci.SshNet.Messages.Transport.KeyExchangeInitMessage.Process(Session session)
at Renci.SshNet.Session.MessageListener()
--- End of stack trace from previous location ---
at Renci.SshNet.Session.WaitOnHandle(WaitHandle waitHandle, TimeSpan timeout)
at Renci.SshNet.Session.WaitOnHandle(WaitHandle waitHandle)
at Renci.SshNet.Session.Connect()
at Renci.SshNet.BaseClient.CreateAndConnectSession()
at Renci.SshNet.BaseClient.Connect()
at <my code>

Code executed:

var sshClient = new Renci.SshNet.SshClient(hostname, port, username, password);
sshClient.Connect();

I understand this is a Wine specific issue, because the bcrypt.dll / ncrypt.dll are heavily stubbed under Wine and Windows CNG (ECDH kex algorithms) is not fully supported as of right now. So not really a SSH.NET bug.

I was able to circumvent the issue by removing ECDH key exchange algorithms before connecting via my SshClient:

foreach (var algo in sshClient.ConnectionInfo.KeyExchangeAlgorithms.Keys.ToList())
{
    if (!algo.StartsWith("diffie-hellman-group", StringComparison.Ordinal))
        sshClient.ConnectionInfo.KeyExchangeAlgorithms.Remove(algo);
}

Obviously this is not really a good solution.

As a suggestion, it would be nice to have an option to switch to the BouncyCastle implementations via e.g. some config option.

For example in KeyExchangeECCurve25519:

        public override void Start(Session session, KeyExchangeInitMessage message, bool sendClientInitMessage)
        {
            base.Start(session, message, sendClientInitMessage);
#if NET
            if (!_forceBouncyCastleImpl && System.OperatingSystem.IsWindowsVersionAtLeast(10))
            {
                _impl = new BclImpl();
            }
            else
#endif
            {
                _impl = new BouncyCastleImpl();
            }

            StartImpl();
        }

where _forceBouncyCastleImpl is just some placeholder to force using the BouncyCastle implementation that can be somehow configured.

(As a side note: This issues did not occur with older SSH.NET versions or on .NET Framework)

Dominant language
C#
Stars
4.4k
Forks
993
Avg merge
9d 21h
Merged PRs (30d)
1

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from sshnet/SSH.NET

All issues in sshnet/SSH.NET

Similar issues

More C# issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.