2014-10-30 13 views
6

Tôi đang cố mở phiên ứng dụng SSH từ ứng dụng Android của mình. Đang cố gắng kết nối với một thiết bị trên mạng cục bộ (một Raspberry Pi). Tôi đang sử dụng thư viện SSHJ phiên bản 0.10.0. Nó không thành công trong cuộc gọi ssh.connect(), với số TransportException mà cuối cùng là do số NoSuchAlgorithmException. Hãy tham khảo cây ngoại lệ bên dưới. câyNgoại lệ SSHJ của Android khi kết nối() - "Triển khai KeyFactory ECDSA không tìm thấy"

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) { 
    ; 
} 

Ngoại lệ:

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 

thông tin hệ thống khác:

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

tôi đã sử dụng sự hỗ trợ phụ thuộc maven trong Android Studio để mang lại JAR SSHJ và nó kéo theo sau ba thư viện ngoài jar SSH0 v0.10.0 ...

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

Không có đầu mối bắt đầu từ ngoại lệ này ... bất kỳ đề xuất nào được đánh giá cao! Cảm ơn.

UPDATE: 31-Oct-2014

Theo đề nghị của LeeDavidPainter, tôi bao gồm JAR SpongyCastle 1.51.0 và thêm dòng này ở đầu trang:

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

Tôi bây giờ nhận được một ngoại lệ khác trên cùng một dòng:

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 

Cũng lưu ý rằng tôi cũng đã thử dòng sau, với kết quả tương tự:

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

Tôi có một ứng dụng trên điện thoại của tôi mà về cơ bản làm chính xác những gì tôi muốn đạt được - nó được gọi là RaspberryPiController - nó kết nối với RPi của bạn thông qua SSH với tên truy cập và mật khẩu auth. Điều này làm việc tốt, vì vậy nó sẽ có vẻ không phải là một vấn đề mạng.

Trả lời

0

Không thể gặp bất kỳ đâu với vấn đề này trong SSHJ, vì vậy hãy quyết định thử JSch một lần thử có chức năng tương tự. Nó có sẵn như là một repo maven là tốt - Tôi đã sử dụng jsch version 0.1.51 ('com.jcraft: jsch: 0.1.51').

Lần đầu tiên nó hoạt động với đoạn mã này;

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(); 
} 

Có vẻ như triển khai mạnh mẽ hơn khi sử dụng so với SSHJ - hoặc hiển thị này có thể do họ chọn thời gian chờ khá thận trọng. Ví dụ: nếu thiết bị mục tiêu bị tắt, phiên.connect() cuộc gọi sẽ, theo mặc định, tiếp tục cố gắng để kết nối cho một cái gì đó như 20 giây trước khi bỏ cuộc.

4

Tàu Android có phiên bản BouncyCastle bị cắt giảm không bao gồm thuật toán ECDSA. Vì vậy, ngay cả khi bạn bao gồm phiên bản đầy đủ trong đường dẫn lớp học của bạn, phiên bản thời gian chạy Android sẽ được chọn và sử dụng.

Bạn có thể muốn xem http://rtyley.github.io/spongycastle/ được tạo để giải quyết vấn đề này, phiên bản đóng gói lại của Bouncycastle có thể được cài đặt như một nhà cung cấp JCE riêng biệt trong Android. Chỉ cần cài đặt nó làm nhà cung cấp JCE mặc định trước khi bạn thử kết nối với SSHJ (chưa được kiểm tra).

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

Cảm ơn bạn đã đề xuất - Tôi đã cho nó đi và bây giờ nhận được một ngoại lệ khác - java.security.spec.InvalidKeySpecException: thông số khóa không được nhận dạng. Nó xảy ra tại cùng một chỗ - trên ssh.connect() gọi. Tôi đã cập nhật câu hỏi ở trên với các chi tiết. –

+0

Tôi có cùng một vấn đề và giới thiệu JCE mới này cho cùng một vấn đề như nhận xét ngay trên ... – gregoiregentil

+1

Trên Android 4.4.4, tôi phải gọi 'Security.removeProvider ("BC") '** trước ** gọi 'Security.insertProviderAt (new BouncyCastleProvider(), Security.getProviders(). Length + 1)'. Nếu không, 'BouncyCastleProvider' chưa bao giờ được thêm vào danh sách các nhà cung cấp. – EricRobertBrewer

0

Rất có thể Jsch đã làm việc vì nó không hỗ trợ thuật toán Elliptic Curve cho SSH AFAIK. Nếu bạn không cần thuật toán Elliptic Curve thì đó là câu trả lời của bạn.

Các vấn đề liên quan