2016-10-31 6 views
5

У меня возникла странная проблема после обновления версии java 1.8. Я использую jsch-0.1.54.jar в одной из наших служебных программ для загрузки файлов из разных мест. Эта конкретная утилита использовалась почти 4-5 лет без каких-либо проблем (тогда она была jsch-0.1.48). В то время среда была java 1.6. Недавно мы обновились до версии java 1.8, и в результате мы обновили эту специальную утилиту. Теперь мы сталкиваемся с какой-то странной проблемой, и это происходит иногда, и большую часть времени загрузка файлов является префектом.Подпись длиной не верна: получил 127, но ожидал 128

Журнал ошибок

INFO: SSH_MSG_KEXDH_INIT sent 
INFO: expecting SSH_MSG_KEXDH_REPLY 
INFO: Disconnecting from SRV2000 port 22 
2016-10-28 08:42:18:0576 ERROR [main] net.AerisAbstractMethod - Failed to open connection 
com.jcraft.jsch.JSchException: Session.connect: java.security.SignatureException: Signature length not correct: got 127 but was expecting 128 
    at com.jcraft.jsch.Session.connect(Session.java:565) 
    at com.jcraft.jsch.Session.connect(Session.java:183) 
    at com.aeris.net.AerisSFTPMethod.connectToServer(AerisSFTPMethod.java:65) 
    at com.aeris.net.AerisAbstractMethod.getListOfFiles(AerisAbstractMethod.java:143) 
    at com.aeris.worker.AerisUploaderDownloader.performUploadDownloadListing(AerisUploaderDownloader.java:112) 
    at com.aeris.main.AerisCommonSftpUtility.main(AerisCommonSftpUtility.java:102) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at java.lang.reflect.Method.invoke(Unknown Source) 
    at com.simontuffs.onejar.Boot.run(Boot.java:340) 
    at com.simontuffs.onejar.Boot.main(Boot.java:166) 

Успех журнала (в большинстве случаев это успех)

INFO: SSH_MSG_KEXDH_INIT sent 
INFO: expecting SSH_MSG_KEXDH_REPLY 
INFO: ssh_rsa_verify: signature true 
WARN: Permanently added 'SRV2000' (RSA) to the list of known hosts. 
INFO: SSH_MSG_NEWKEYS sent 
INFO: SSH_MSG_NEWKEYS received 
INFO: SSH_MSG_SERVICE_REQUEST sent 
INFO: SSH_MSG_SERVICE_ACCEPT received 
INFO: Authentications that can continue: publickey,password,keyboard-interactive 
INFO: Next authentication method: publickey 
INFO: Authentication succeeded (publickey). 
2016-10-28 08:36:48:0794 INFO [main] net.AerisAbstractMethod - Session connected to server 
2016-10-28 08:36:48:0794 INFO [main] net.AerisAbstractMethod - Opening SFTP channel.. 
2016-10-28 08:36:48:0810 INFO [main] net.AerisAbstractMethod - Connecting to server through channel. 
2016-10-28 08:36:48:0857 INFO [main] net.AerisAbstractMethod - Connection successful. 
2016-10-28 08:36:48:0857 INFO [main] net.AerisAbstractMethod - Changing to directory:C:/interfaces/ib/wf/work 
2016-10-28 08:36:48:0888 INFO [main] net.AerisAbstractMethod - Start file Listing of the remote directory:C:/interfaces/ib/wf/work 

     0 Oct 28, 2016 04:15 ./ 
     0 Oct 28, 2016 04:15 ../ 

Я сделал полный анализ с Ван Дейка (SFTP поставщика программного обеспечения), но ничего не нашел ошибка с этой целью. Я также пытался использовать sftp с помощью разных инструментов, но я не получаю никаких ошибок. Ниже приведен фрагмент кода для подключения SFTP-сервера. Может ли кто-нибудь помочь в этом вопросе?

protected void connectToServer() throws AerisConnectionException { 
     JSch jSch =(JSch)this.client; 
     try { 

      session = jSch.getSession(config.getUsername(), config.getRemoteserver(), config.getPort()); 
      LOGGER.info("Creating SSH Session using Username:"+config.getUsername()+ " Server :" +config.getRemoteserver()+ " at PORT:"+config.getPort()); 
      if(config.getAuth().equalsIgnoreCase("PASSWD")||config.getAuth().equalsIgnoreCase("KEYPASS")){ 
       LOGGER.info("Setting password ..."); 
       session.setPassword(config.getPassword()); 
      } 

      Properties jShconfig = new Properties();    
      jShconfig.put("StrictHostKeyChecking", "no"); 
      jShconfig.put("PreferredAuthentications", 
         "publickey,password,keyboard-interactive"); 
      jShconfig.put("LogLevel", "VERBOSE"); 


      LOGGER.info("Setting timeout to "+config.getTimeOut()); 
      session.setTimeout(config.getTimeOut()*1000); 
      session.setConfig(jShconfig);   

      session.connect(); 
      LOGGER.info("Session connected to server"); 
      this.connected=true; 

     } catch (JSchException e) { 
      LOGGER.error("Failed to open connection ",e); 
      throw new AerisConnectionException("Failed to open connection."); 
     } 

    } 
+0

похоже, что сервер иногда пытается использовать устаревшее шифрование, которое java 8 больше не поддерживает. – maxpovver

+0

Можете ли вы найти стоп-код оригинального исключения (как поймали в Session.java:565)? –

+0

И, конечно же, добавить файл журнала JSch. –

ответ

5

Хотя было бы неплохо иметь StackTrace, чтобы подтвердить, я буду держать пари, что сервер использует ПДС «хозяина» ключ для аутентификации и ошибочно «зачистка» лидирующего нуля в редких случаях.

значения RSA подписи (и зашифрованные значения также), определяемые PKCS # 1, SSH uses (как и многие другие вещи, включая SSL), которые необходимы для быть закодирован как октета строки фиксированной длины «к» равна длина, требуемая для кодирования модуля, или неофициально «того же размера, что и модуль». Однако, поскольку лежащее в основе математическое значение представляет собой большое неотрицательное целое число (без знака), в частности modexp (s, d, n), исторически некоторые реализации опущены ведущими нулевыми октетами - это упущение, которое справедливо при обработке значения как целого - в результате получается закодированное значение, которое иногда короче, чем должно быть.

Знак RSA (или зашифрованного) является фактически равномерным случайным числом в (1, n). Таким образом, когда ключ RSA, используемый сервером, имеет размер «круглого двоичного» размера, такой как 1024, как здесь, эта обрезка произойдет примерно 1 в 200 раз в случайном порядке или 400, если обрезается как подписанное число.

я не знаю, но на тестировании я подтверждаю, что (Oracle) Java-действительно принимает такого «короткое» значение для Signature типа RSA или как на самом деле используются здесь SHA1withRSA, оба из которых подразумевает схему PKCS1-v1_5 , но Java 7 и 8 выбрасывают исключение, которое вы видели. OTOH как OpenSSH, так и PuTTY (также используемые WinSCP и FileZilla) принимают «короткие» значения, а всегда отправляют правильные значения длины; это постэлианское поведение может затруднить обнаружение, когда одноранговый партнер ведет себя так плохо. (Примечание: я проверил OpenSSH 5.5 и 7.3, самый старый и новейший я имею под рукой, но только текущий PuTTY 0.67, потому что это все, что я держу в сети.)

Вы можете попробовать указать разработчику программного обеспечения сервера на опубликованные стандарты , но это может не принести пользы. Вы могли бы спросить jcraft о специальном случае; они уже имеют логику в делах DSA и ECDSA для mpint/ASN.1, которые, как я могу утверждать, одинаково уродливы. Или , если у сервера есть другой (полезный) ключ, запросите, сконфигурировав "server_host_key", чтобы НЕ включать ssh-rsa - проще всего получить существующий/по умолчанию список, разбить, удалить "ssh-rsa" (и проверить не пустым) и воссоединиться, а не возможно запутывая ваших пользователей и/или (co) сопровождающих, перечисляя современные алгоритмы.

+0

Спасибо, за ваш ответ. Я согласен с вами, и ваше объяснение очень соответствует поведению утилиты. –