Отпечатки 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);
}
Со следующими изменениями:
- 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);
}
}