2014-10-30 30 views
6

Sto provando ad aprire una sessione client SSH dalla mia app Android. Cercando di connettersi a un dispositivo sulla rete locale (un Raspberry Pi). Sto usando la versione di libreria SSHJ 0.10.0. Non riesce sulla chiamata ssh.connect(), con un TransportException che è in definitiva causato da un NoSuchAlgorithmException. Fare riferimento a albero delle eccezioni di seguito. alberoEccezione SSHJ Android su connect() - "Impossibile trovare l'implementazione ECDSA KeyFactory"

SSHClient ssh = new SSHClient(new AndroidConfig()); 
Session session = null; 

try {  
    //ssh.loadKnownHosts(); 

    // Exception thrown on this line 
    ssh.connect("192.168.1.109", 22); 

    // Doesn't reach below 
    ssh.authPassword("user", "password"); 
    session = ssh.startSession(); 
} 
catch (net.schmizz.sshj.transport.TransportException ex) { 
    ; 
} 

Eccezione:

net.schmizz.sshj.transport.TransportException 
net.schmizz.sshj.common.SSHException 
    net.schmizz.sshj.common.SSHRuntimeException 
    java.security.GeneralSecurityException: java.security.NoSuchAlgorithmException: KeyFactory ECDSA implementation not found 
    java.security.NoSuchAlgorithmException: KeyFactory ECDSA implementation not found 

Altre informazioni sistema:

SSHJ library : v0.10.0 
Android device : Galaxy Note 3 running Android 4.4.2 

ho usato il supporto Maven dipendenza nel Android Studio per portare nel vaso SSHJ e tirato nei seguenti tre librerie in aggiunta al vaso SSHJ v0.10.0 ...

bouncy castle... 
    bcpkix-jdk15on-1.50.jar 
    bcprov-jdk15on-1.50.jar 
logging.... 
    slf4j-api-1.7.7.jar 

Non ho idea di dove iniziare con questa eccezione ... qualsiasi suggerimento apprezzato! Grazie.

UPDATE: 31-ott-2014

Come suggerito da LeeDavidPainter, ho incluso il JAR SpongyCastle 1.51.0 e ha aggiunto questa riga in alto:

Security.insertProviderAt(new org.spongycastle.jce.provider.BouncyCastleProvider(), 1); 

Ora sto ricevendo un'eccezione diversa sulla stessa linea:

net.schmizz.sshj.transport.TransportException 
net.schmizz.sshj.common.SSHException 
    net.schmizz.sshj.common.SSHRuntimeException 
    java.security.GeneralSecurityException: java.security.spec.InvalidKeySpecException: key spec not recognised 
    java.security.spec.InvalidKeySpecException: key spec not recognised 

Nota anche ho provato la seguente riga, con lo stesso risultato:

Security.addProvider(new org.spongycastle.jce.provider.BouncyCastleProvider()); 

ho un'altra app sul mio cellulare che è fondamentalmente facendo esattamente quello che voglio ottenere - la sua chiamata RaspberryPiController - si collega al vostro RPI su SSH con nome utente e password di autenticazione. Funziona bene, quindi sembra che non sia un problema di rete.

risposta

0

Impossibile ottenere da nessuna parte con questo problema in SSHJ, così ha deciso di dare una prova JSch che offre le stesse funzionalità. È disponibile anche come repo di programmazione. Ho usato jsch version 0.1.51 ('com.jcraft: jsch: 0.1.51').

Ha funzionato la prima volta con questo frammento di codice;

import com.jcraft.jsch.ChannelExec; 
import com.jcraft.jsch.JSch; 
import com.jcraft.jsch.JSchException; 

import java.io.ByteArrayOutputStream; 
import java.util.Properties; 

JSch jsch = new JSch(); 
com.jcraft.jsch.Session session = null; 
String result = ""; 

try {  
    session = jsch.getSession("user", "192.168.1.109", 22); 
    session.setPassword("password"); 

    // Avoid asking for key confirmation 
    Properties prop = new Properties(); 
    prop.put("StrictHostKeyChecking", "no"); 
    session.setConfig(prop); 
    session.connect(); 

    // SSH Channel 
    ChannelExec channel = (ChannelExec)session.openChannel("exec"); 
    ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
    channel.setOutputStream(stream); 

    // Execute command 
    channel.setCommand("ls -ltr"); 
    channel.connect(1000); 
    java.lang.Thread.sleep(500); // this kludge seemed to be required. 
    channel.disconnect(); 

    result = stream.toString(); 
} 
catch (JSchException ex) { 
    String s = ex.toString(); 
    System.out.println(s); 
} 
catch (InterruptedException ex) { 
    String s = ex.toString(); 
    System.out.println(s); 
} 
finally { 
    if (session != null) 
    session.disconnect(); 
} 

ci si sente come un'implementazione più robusto quando lo si utilizza rispetto a SSHJ - o questa impressione potrebbe essere causato da selezionandoli timeout piuttosto conservatori. Ad esempio, se il dispositivo di destinazione è spento, la sessione.connect() call, per impostazione predefinita, continua a provare a connettersi per qualcosa come 20 secondi prima di arrendersi.

4

Android viene fornito con una versione ridotta di BouncyCastle che non include gli algoritmi ECDSA. Pertanto, anche se includi la versione completa nel tuo percorso di classe, la versione runtime di Android verrà rilevata e utilizzata.

Si potrebbe voler guardare a http://rtyley.github.io/spongycastle/ che è stato creato per aggirare questo, è una versione riconfezionata di Bouncycastle che può essere installato come fornitore JCE separato in Android. Basta installarlo come provider JCE predefinito prima di provare a connettersi con SSHJ (non testato).

Security.insertProviderAt(new org.spongycastle.jce.provider.BouncyCastleProvider(), 1); 
+0

Grazie per il suggerimento - ho dato un tentativo e ora sto ottenendo un'eccezione diversa - java.security.spec.InvalidKeySpecException: specifica chiave non riconosciuta. Succede nello stesso punto - sulla chiamata ssh.connect(). Ho aggiornato la domanda sopra con i dettagli. –

+0

Ho lo stesso problema e l'introduzione di questo nuovo JCE dà lo stesso problema del commento appena sopra ... – gregoiregentil

+1

Su Android 4.4.4, ho dovuto chiamare 'Security.removeProvider (" BC ")' ** prima ** chiamata 'Security.insertProviderAt (new BouncyCastleProvider(), Security.getProviders(). Length + 1)'. In caso contrario, il 'BouncyCastleProvider' non è mai stato aggiunto all'elenco dei provider. – EricRobertBrewer

0

Jsch ha probabilmente funzionato perché non supporta gli algoritmi Elliptic Curve per SSH AFAIK. Se non hai bisogno degli algoritmi di curva ellittica, questa è la tua risposta.

Problemi correlati