Java - JSch Отключено от сервера, несмотря на пару ключей [duplicate]

Что вам нужно знать:

    текст, который представляет несколько строк, также содержит непечатаемые символы между строками (мы называем их разделителями строк), как возврат каретки (CR - в строковых литералах, представленных как "\r") line line (LF - в строковых литералах, представленных как "\n")
  • , когда вы читаете данные с консоли, это позволяет пользователю вводить свой ответ, и когда он будет сделан, ему необходимо как-то подтверждают этот факт. Для этого пользователю необходимо нажать клавишу «enter» / «return» на клавиатуре. Важно то, что этот ключ, помимо обеспечения помещения пользовательских данных в стандартный вход (представленный System.in, который читается Scanner), также отправляет зависимые от ОС разделители строк (например, для Windows \r\n) после этого. Поэтому, когда вы запрашиваете у пользователя значение типа age, а пользовательские типы 42 и нажатия вводятся, стандартный ввод будет содержать "42\r\n".

Проблема

Scanner#nextInt (и другие методы Scanner#nextType) не позволяют сканеру потреблять эти разделители строк. Он прочитает их из System.in (как еще Сканер знал бы, что больше нет цифр от пользователя, которые представляют age значение, чем перед пробелом?), Который удалит их со стандартного ввода, но он также будет кешем эти разделители строк внутри. Нам нужно помнить, что все методы Scanner всегда сканируются, начиная с кэшированного текста.

Теперь Scanner#nextLine() просто собирает и возвращает все символы , пока не найдет разделители строк (или конец потока). Но поскольку разделители строк после прочтения номера из консоли сразу обнаруживаются в кеше сканера, он возвращает пустую строку, что означает, что сканер не смог найти символ до этих разделителей строк (или конца потока). BTW nextLine также потребляет эти разделители строк.

Решение

Поэтому, когда вы хотите запросить номер, а затем для всей строки и избежать этой пустой строки в результате nextLine, либо

  • после nextInt поместить дополнительный nextLine вызов, чтобы использовать разделители строк из кеша сканеров,
  • не использовать nextInt (ни next, ни любое nextTYPE ] методов). Вместо этого прочитайте целые строки данных по строке nextLine и номера разбора из каждой строки (при условии, что одна строка содержит только одно число) для правильного типа, например int через Integer.parseInt.

BTW: Scanner#nextType методы могут пропускать разделители (по умолчанию все пробелы, такие как вкладки, разделители строк), в том числе кэшированные сканером, пока они не найдут следующее значение без разделителя (токен). Благодаря этому для ввода типа "42\r\n\r\n321\r\n\r\n\r\nfoobar" код

int num1 = sc.nextInt();
int num2 = sc.nextInt();
String name = sc.next();

сможет правильно назначить num1=42 num2=321 name=foobar.

10
задан Martin Prikryl 30 September 2015 в 06:49
поделиться

2 ответа

Вы пытаетесь пропустить проверку ключа хоста, установив StrictHostKeyChecking на no.

Но вы должны сделать это перед проверкой, то есть перед session.connect().


В любом случае, вы никогда не должны этого делать, если вам не нужна безопасность. Проверка ключа хоста защищает вас от атак man-in-the-middle .

Вместо этого настройте ожидаемый ключ хоста, чтобы JSch проверил его.

Например:

  • Вызов JSch.setKnownHosts, обеспечивающий путь к файлу .ssh/known_hosts. Для генерации .ssh/known_hosts -подобного файла вы можете использовать команду ssh-keyscan из OpenSSH. Если вы подключаетесь к серверу * nix, вы должны иметь доступную команду, просто запустите
    ssh-keyscan example.com > known_hosts
    
    . Он будет иметь формат, такой как:
    example.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0hVqZOvZ7yWgie9OHdTORJVI5fJJoH1yEGamAd5G3werH0z7e9ybtq1mGUeRkJtea7bzru0ISR0EZ9HIONoGYrDmI7S+BiwpDBUKjva4mAsvzzvsy6Ogy/apkxm6Kbcml8u4wjxaOw3NKzKqeBvR3pc+nQVA+SJUZq8D2XBRd4EDUFXeLzwqwen9G7gSLGB1hJkSuRtGRfOHbLUuCKNR8RV82i3JvlSnAwb3MwN0m3WGdlJA8J+5YAg4e6JgSKrsCObZK7W1R6iuyuH1zA+dtAHyDyYVHB4FnYZPL0hgz2PSb9c+iDEiFcT/lT4/dQ+kRW6DYn66lS8peS8zCJ9CSQ==
    
    И ссылается на сгенерированный файл known_hosts в вашем JSch-коде. Если вы находитесь в Windows, вы можете получить сборку Windows из проекта Win32-OpenSSH или Git для Windows.
  • Вызов JSch.getHostKeyRepository().add(), чтобы обеспечить ожидаемый ключ хоста (например, жестко запрограммированные, как и другие учетные данные). См. Создание экземпляра JSch HostKey из открытого ключа в формате .pub .
16
ответ дан Martin Prikryl 28 August 2018 в 16:53
поделиться

Кроме того: «Cygwin», я предполагаю, что вы имеете в виду sshd или sftpd, потому что сам Cygwin не выполняет SSH.

В любом случае, если вы хотите, чтобы клиент Jsch принимал любой ключ от хоста, переместите .setConfig, который устанавливает StrictHostKeyChecking no так, как раньше session.connect(). В качестве альтернативы вы должны предоставить доступ к хранилищу, содержащему правильный ключ (ы) для ваших хостов (ов), как объясняет @Martin, - и вы всегда должны делать это при подключении к чему-либо, кроме «localhost» или, возможно, к машине, тот же физически защищенный сегмент сети (например, проводной сетевой концентратор в одной комнате).

1
ответ дан dave_thompson_085 28 August 2018 в 16:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: