2016-10-31 20 views
5

Mam do czynienia z dziwnym problemem po aktualizacji java 1.8. Używam jsch-0.1.54.jar w jednym z naszych programów narzędziowych do pobierania plików z różnych miejsc. Ten szczególny program był używany przez prawie 4-5 lat bez żadnego problemu (wtedy był to jsch-0.1.48). W tym czasie środowiskiem było java 1.6. Niedawno zaktualizowaliśmy program do wersji 1.0, w wyniku czego zaktualizowaliśmy to narzędzie. Teraz napotykamy na dziwny problem i pojawia się on sporadycznie, a większość czasu pobierania plików jest perfekcyjna.Podpis długość niepoprawna: 127, ale spodziewałem się 128

dziennika Błąd

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) 

Sukces Log: (w większości przypadków jest to sukces)

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 ../ 

zrobiłem pełną analizę z Vandyke (SFTP dostawcą oprogramowania), ale nie znaleźliśmy żadnych błąd w tym celu. Próbowałem też sftp używając różnych narzędzi, ale nie dostaję żadnego błędu. Poniżej znajduje się fragment kodu do połączenia z serwerem SFTP. Czy ktokolwiek może pomóc w tej sprawie?

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

Wygląda na to, że serwer czasami próbuje użyć przestarzałego szyfrowania, którego java 8 nie obsługuje już – maxpovver

+0

Czy możesz znaleźć stację wywoławczą oryginalnego wyjątku (złapaną w Session.java:565)? –

+0

I, oczywiście, dodać plik dziennika JSch. –

Odpowiedz

5

Chociaż byłoby miło mieć StackTrace potwierdzić, założę serwer używa RSA „host” klucz do uwierzytelniania i jest błędnie „przycinanie” zerem w rzadkich przypadkach.

wartości RSA Podpis (i szyfrowane wartości również) zdefiniowane przez PKCS # 1, który SSH uses (podobnie jak wiele innych rzeczy w tym SSL), muszą być zakodowane jako ciąg oktet stałej długości „k” równy długość wymagana do kodowania modułu lub nieformalnie "ten sam rozmiar co moduł". Ponieważ jednak podstawową wartością matematyczną jest duża nieujemna (inaczej niepodpisana) liczba całkowita, konkretnie modexp (s, d, n), historycznie niektóre implementacje pomijały wyprzedzające oktety zerowe - pominięcie, które jest ważne, gdy traktujemy wartość jako liczbę całkowitą - w wyniku czego zakodowana wartość jest czasami krótsza niż powinna.

Wartość podpisu RSA (lub zaszyfrowanego) jest w rzeczywistości równomierną liczbą losową w (1, n). Tak więc, gdy klucz RSA używany przez serwer ma rozmiar "okrągłego binarnego", jak 1024, jak tutaj, przycinanie to stanie się około 1 w 200 razy losowo, lub 400, jeśli zostanie przycięte jako podpisany numer.

ja nie wiem, ale na badania potwierdzić, że (Oracle) Java 6 bierze taki „krótki” wartość dla Signature typ RSA lub za faktycznie wykorzystane tutaj SHA1withRSA, z których oba oznaczać schemat PKCS1-v1_5 , ale Java 7 i 8 rzut wyjątek, który widziałem. OTOH zarówno OpenSSH, jak i PuTTY (używane również przez WinSCP i FileZillę) akceptują "krótkie" wartości, podczas gdy zawsze wysyłają poprawne wartości długości do; to postelskie zachowanie może utrudnić wykrycie, kiedy ktoś w ten sposób źle się zachowuje. (Uwaga: Sprawdziłem OpenSSH 5.5 i 7.3, najstarszy i najnowszy mam do dyspozycji pod ręką, ale tylko bieżący PuTTY 0.67, ponieważ to wszystko, co pozostaję w Internecie.)

Możesz spróbować skierować implementatora oprogramowania serwera do opublikowanych standardów , ale to może nie przydać się dobrze. Możesz poprosić jcraft o specjalny przypadek; mają już logikę w przypadkach DSA i ECDSA dla mpint/ASN.1, które, jak twierdzę, są równie brzydkie. Lub , jeśli serwer ma inny klucz (można użyć), należy poprosić, aby, konfigurując "server_host_key", aby NIE zawierał ssh-rsa - najłatwiej po prostu wybierz istniejącą/domyślną listę, podziel, usuń "ssh-rsa" (i sprawdź, czy nie jest pusty) i dołącz ponownie, zamiast ewentualnie myląc użytkowników i/lub (współ) opiekunów, wymieniając dzisiejsze specyficzne algorytmy.

+0

Dzięki za odpowiedź. Zgadzam się z tobą, a twoje wyjaśnienie jest bardzo zgodne z zachowaniem narzędzia. –