📜  如何在Android中通过SSH远程执行命令?

📅  最后修改于: 2021-05-13 17:03:44             🧑  作者: Mango

SSH协议使用加密来保护客户端和服务器之间的连接。所有用户身份验证,命令,输出和文件传输都经过加密,以防止受到网络攻击。通常,您将需要SSH到您的云虚拟机或远程Shell中。通常,我们需要一个SSH客户端来建立SSH连接。对于Windows,免费(免费)GUI客户端PuTTY用于此目的。这是在PuTTY中访问远程Linux shell的样子:

以下教程说明了如何在android中实现相同的功能。注意,我们将使用Java语言实现该项目。库:Apache MINA SSHD

分步实施

步骤1:创建一个新项目

要在Android Studio中创建新项目,请参阅如何在Android Studio中创建/启动新项目。请注意,选择Java作为编程语言。

步骤2:添加依赖项

现在,我们需要添加必需的依赖项才能使用apache mina sshd库。打开项目目录中的app / src / build.gradle文件,并在依赖项下添加以下内容:

步骤3:在您的AndroidManifest.xml文件中向互联网添加权限

src / res / AndroidManifest.xml文件的 标记内的以下两行中添加。

步骤4:修改字符串.xml文件

打开app> src> main> res> values>字符串.xml并添加以下代码:

XML

    gfg_ssh
    Host
    Port
    22
    Username
    Password
    SEND


XML


  
    
  
        
  
        
  
        
  
        
  
        


XML


  
    
  


Java
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
  
import androidx.appcompat.app.AppCompatActivity;
  
public class MainActivity extends AppCompatActivity {
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
  
    public void authenticate(View view) {
        
        // Create an intent for sshActivity
        Intent intent = new Intent(this, sshActivity.class);
  
        // Declare fields
        EditText editText = (EditText) findViewById(R.id.editText);
        EditText portField = (EditText) findViewById(R.id.portField);
        EditText usernameField = (EditText) findViewById(R.id.usernameField);
        EditText passwordField = (EditText) findViewById(R.id.passwordField);
          
        // Get input data from fields
        String host = editText.getText().toString();
        String port = portField.getText().toString();
        String username = usernameField.getText().toString();
        String password = passwordField.getText().toString();
  
        // Pass on data to sshActivity via intent
        intent.putExtra("host", host);
        intent.putExtra("port", port);
        intent.putExtra("username", username);
        intent.putExtra("password", password);
        startActivity(intent);
        finish();
    }
}


Java
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
  
import androidx.appcompat.app.AppCompatActivity;
  
import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.channel.ClientChannel;
import org.apache.sshd.client.channel.ClientChannelEvent;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.common.channel.Channel;
import org.apache.sshd.server.forward.AcceptAllForwardingFilter;
  
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.EnumSet;
import java.util.concurrent.TimeUnit;
  
public class sshActivity extends AppCompatActivity {
  
    ClientChannel channel;
    TextView shellOutput;
    String host, username, password;
    Integer port;
    String command;
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ssh);
  
        // set output field
        shellOutput = findViewById(R.id.textView);
  
        // Get user credentials from indent
        Intent intent = getIntent();
        host = intent.getStringExtra("host");
        port = Integer.parseInt(intent.getStringExtra("port"));
        username = intent.getStringExtra("username");
        password = intent.getStringExtra("password");
  
        // Command which will be executed
        command = "pwd\n";
          
        // Setting user.com property manually 
        // since isn't set by default in android
        String key = "user.home";
        Context Syscontext;
        Syscontext = getApplicationContext();
        String val = Syscontext.getApplicationInfo().dataDir;
        System.setProperty(key, val);
  
        // Creating a client instance
        SshClient client = SshClient.setUpDefaultClient();
        client.setForwardingFilter(AcceptAllForwardingFilter.INSTANCE);
        client.start();
  
        // Starting new thread because network processes 
        // can interfere with UI if started in main thread
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    // Connection establishment and authentication
                    try (ClientSession session = client.connect(username, host, port).verify(10000).getSession()) {
                        session.addPasswordIdentity(password);
                        session.auth().verify(50000);
                        System.out.println("Connection establihed");
  
                        // Create a channel to communicate
                        channel = session.createChannel(Channel.CHANNEL_SHELL);
                        System.out.println("Starting shell");
  
                        ByteArrayOutputStream responseStream = new ByteArrayOutputStream();
                        channel.setOut(responseStream);
  
                        // Open channel
                        channel.open().verify(5, TimeUnit.SECONDS);
                        try (OutputStream pipedIn = channel.getInvertedIn()) {
                            pipedIn.write(command.getBytes());
                            pipedIn.flush();
                        }
  
                        // Close channel
                        channel.waitFor(EnumSet.of(ClientChannelEvent.CLOSED),
                                TimeUnit.SECONDS.toMillis(5));
  
                        // Output after converting to string type
                        String responseString = new String(responseStream.toByteArray());
                        System.out.println(responseString);
                        shellOutput.setText(responseString);
                          
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        client.stop();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
    }
}


步骤5:建立使用者介面

我们将在我们的应用程序中进行两项活动。

  • MainActivity :在这里,我们将输入登录详细信息
  • sshActivity :在这里,我们将看到shell输出。

使用activity_main.xml文件:

现在,导航至应用程序> src> main> res>布局> activity_main.xml ,并将以下代码添加到文件中。

XML格式



  
    
  
        
  
        
  
        
  
        
  
        

首先,通过右键单击活动文件夹(com.example.gfg_ssh)创建一个新的活动sshActivity,然后选择“新建”>“活动”>“空活动”,然后 现在,将以下代码添加到该活动的UI的activity_ssh.xml文件中。

XML格式



  
    
  

步骤6:使用MainActivity。 Java文件

转到MainActivity。 Java文件并参考以下代码。下面是MainActivity的代码。 Java文件。在代码内部添加了注释,以更详细地了解代码。

Java

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
  
import androidx.appcompat.app.AppCompatActivity;
  
public class MainActivity extends AppCompatActivity {
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
  
    public void authenticate(View view) {
        
        // Create an intent for sshActivity
        Intent intent = new Intent(this, sshActivity.class);
  
        // Declare fields
        EditText editText = (EditText) findViewById(R.id.editText);
        EditText portField = (EditText) findViewById(R.id.portField);
        EditText usernameField = (EditText) findViewById(R.id.usernameField);
        EditText passwordField = (EditText) findViewById(R.id.passwordField);
          
        // Get input data from fields
        String host = editText.getText().toString();
        String port = portField.getText().toString();
        String username = usernameField.getText().toString();
        String password = passwordField.getText().toString();
  
        // Pass on data to sshActivity via intent
        intent.putExtra("host", host);
        intent.putExtra("port", port);
        intent.putExtra("username", username);
        intent.putExtra("password", password);
        startActivity(intent);
        finish();
    }
}

步骤7:使用sshActivity。 Java文件

这是我们导入Apache MINA SSHD库并通过SSH连接到我们的远程计算机的活动。我们从意图中获取登录数据。下面是sshActivity的代码。 Java文件。在代码内部添加了注释,以更详细地了解代码。

Java

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
  
import androidx.appcompat.app.AppCompatActivity;
  
import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.channel.ClientChannel;
import org.apache.sshd.client.channel.ClientChannelEvent;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.common.channel.Channel;
import org.apache.sshd.server.forward.AcceptAllForwardingFilter;
  
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.EnumSet;
import java.util.concurrent.TimeUnit;
  
public class sshActivity extends AppCompatActivity {
  
    ClientChannel channel;
    TextView shellOutput;
    String host, username, password;
    Integer port;
    String command;
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ssh);
  
        // set output field
        shellOutput = findViewById(R.id.textView);
  
        // Get user credentials from indent
        Intent intent = getIntent();
        host = intent.getStringExtra("host");
        port = Integer.parseInt(intent.getStringExtra("port"));
        username = intent.getStringExtra("username");
        password = intent.getStringExtra("password");
  
        // Command which will be executed
        command = "pwd\n";
          
        // Setting user.com property manually 
        // since isn't set by default in android
        String key = "user.home";
        Context Syscontext;
        Syscontext = getApplicationContext();
        String val = Syscontext.getApplicationInfo().dataDir;
        System.setProperty(key, val);
  
        // Creating a client instance
        SshClient client = SshClient.setUpDefaultClient();
        client.setForwardingFilter(AcceptAllForwardingFilter.INSTANCE);
        client.start();
  
        // Starting new thread because network processes 
        // can interfere with UI if started in main thread
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    // Connection establishment and authentication
                    try (ClientSession session = client.connect(username, host, port).verify(10000).getSession()) {
                        session.addPasswordIdentity(password);
                        session.auth().verify(50000);
                        System.out.println("Connection establihed");
  
                        // Create a channel to communicate
                        channel = session.createChannel(Channel.CHANNEL_SHELL);
                        System.out.println("Starting shell");
  
                        ByteArrayOutputStream responseStream = new ByteArrayOutputStream();
                        channel.setOut(responseStream);
  
                        // Open channel
                        channel.open().verify(5, TimeUnit.SECONDS);
                        try (OutputStream pipedIn = channel.getInvertedIn()) {
                            pipedIn.write(command.getBytes());
                            pipedIn.flush();
                        }
  
                        // Close channel
                        channel.waitFor(EnumSet.of(ClientChannelEvent.CLOSED),
                                TimeUnit.SECONDS.toMillis(5));
  
                        // Output after converting to string type
                        String responseString = new String(responseStream.toByteArray());
                        System.out.println(responseString);
                        shellOutput.setText(responseString);
                          
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        client.stop();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
    }
}

输出:

在登录:

SSH命令执行:

想要一个节奏更快,更具竞争性的环境来学习Android的基础知识吗?
单击此处前往由我们的专家精心策划的指南,以使您立即做好行业准备!