Отпечатки SFTP сервера SHA2 с использованием Renci.SshNet

Я использую Renci.SSHNet, чтобы установить соединение с серверами SFTP. Я сделал это без проблем, но недавно я столкнулся с сервером, к которому я не могу установить соединение через мой код.
Я продолжаю получать следующую ошибку:

Не найдено подходящего метода аутентификации для завершения аутентификации (публичный ключ, клавиатура-интерактив).

Дело в том, что я знаю, что хост, пользователь и пароль верны, поскольку я могу установить соединение с помощью FileZilla. При подключении к другим серверам, использующим FileZilla, я заметил, что отпечатки пальцев для тех, к которым я также могу подключиться с помощью своего кода, генерируются через RSA, а не тот, который доставляет мне проблемы, а именно SHA2.

TL / DR: Что мне интересно, так это то, совместима ли библиотека Renci.SshNet.SFTP с генерируемыми sha-2 отпечатками пальцев, или мне придется использовать для этого другую библиотеку?

3 ответа

Решение

Библиотека SSH.NET пока не поддерживает алгоритмы обмена ключами ECDSA (ecdh-sha2-*) (по состоянию на выпуск 2014.4.6-бета2).

Он поддерживает это:

  • Диффи-Хеллмана-группа обменных sha256
  • Диффи-Хеллмана-группа-обменно-sha1
  • Диффи-Хеллмана-group14-sha1
  • Диффи-Хеллмана-group1-sha1

Ecdh-sha2 - * закомментированы, вероятно, потому что реализация не завершена / протестирована.


Обратите внимание, что сервер может поддерживать несколько алгоритмов и может согласовывать разные алгоритмы с разными клиентами.

Таким образом, тот факт, что вы видите неподдерживаемый тип ключа в FileZilla, не означает, что сервер обязательно настаивает на этом типе ключа.

Понятно, что сервер не требует обмена ключами ECDSA из-за того, что на этапе аутентификации соединение обрывается. Аутентификация происходит только после успешного обмена ключами. Таким образом, ваша корневая проблема не в обмене ключами, а в аутентификации.

Если вам нужна помощь в решении вашей проблемы с аутентификацией, начните новый вопрос, включите соответствующий исходный код, файл журнала FileZilla и объясните нам, что вы сделали для настройки аутентификации на стороне сервера. Также может быть полезен файл журнала на стороне сервера.

У меня была похожая проблема, и мне наконец удалось ее исправить. Ниже решение:

1) Убедитесь, что в решение добавлены следующие директивы.

       using Renci.SshNet;
 using Renci.SshNet.Security;
 using SshNet.Security.Cryptography;

2) Создайте объект ConnectionInfo и добавьте в него необходимые HostKeyAlgorithms.

              var methods = new List<AuthenticationMethod>
           {
            new PasswordAuthenticationMethod("username", "password")
           };
        var connectionInfo = new ConnectionInfo("host", "username", methods.ToArray());
        connectionInfo.HostKeyAlgorithms.Clear();
       
        //ssh-ed25519
        connectionInfo.HostKeyAlgorithms.Add("ssh-ed25519", (data) => { return new KeyHostAlgorithm("ssh-ed25519", new ED25519Key(), data); });
        //ecdsa-sha2-nistp256
        connectionInfo.HostKeyAlgorithms.Add("ecdsa-sha2-nistp256", (data) => { return new KeyHostAlgorithm("ecdsa-sha2-nistp256", new EcdsaKey(), data); });
        //ecdsa-sha2-nistp384
        connectionInfo.HostKeyAlgorithms.Add("ecdsa-sha2-nistp384", (data) => { return new KeyHostAlgorithm("ecdsa-sha2-nistp384", new EcdsaKey(), data); });
        //ecdsa-sha2-nistp521
        connectionInfo.HostKeyAlgorithms.Add("ecdsa-sha2-nistp521", (data) => { return new KeyHostAlgorithm("ecdsa-sha2-nistp521", new EcdsaKey(), data); });
        //ssh-rsa
        connectionInfo.HostKeyAlgorithms.Add("ssh-rsa", (data) => { return new KeyHostAlgorithm("ssh-rsa", new RsaKey(), data); });
        //ssh-dss
        connectionInfo.HostKeyAlgorithms.Add("ssh-dss", (data) => { return new KeyHostAlgorithm("ssh-dss", new DsaKey(), data); });

3) Подключитесь к нужному хосту sftp, используя ConnectionInfo.

       var sftp = new SftpClient(connectionInfo);

            using (sftp)
            {
                try
                {
                     sftp.Connect();
                     Console.WriteLine("Connected");
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }

На основе: https://github.com/sshnet/SSH.NET/blob/1d5d58e17c68a2f319c51e7f938ce6e964498bcc/src/Renci.SshNet/Security/Cryptography/RsaDigitalSignature.cs#L12 .

Со следующими изменениями:

  • OID изменен на sha2-256.
  • хэш изменен с sha1 на sha2-256
      public class RsaSha256DigitalSignature : CipherDigitalSignature, IDisposable
{
  private HashAlgorithm _hash;

  public RsaSha256DigitalSignature(RsaWithSha256SignatureKey rsaKey)
    // custom OID
    : base(new ObjectIdentifier(2, 16, 840, 1, 101, 3, 4, 2, 1), new RsaCipher(rsaKey))
  {
    // custom
    _hash = SHA256.Create();
  }

  protected override byte[] Hash(byte[] input)
  {
    return _hash.ComputeHash(input);
  }

  private bool _isDisposed;

  public void Dispose()
  {
    Dispose(true);
    GC.SuppressFinalize(this);
  }

  protected virtual void Dispose(bool disposing)
  {
    if (_isDisposed)
      return;

    if (disposing)
    {
      var hash = _hash;
      if (hash != null)
      {
        hash.Dispose();
        _hash = null;
      }

      _isDisposed = true;
    }
  }

  ~RsaSha256DigitalSignature()
  {
    Dispose(false);
  }
}
Другие вопросы по тегам