如何在 Android Pie 上 运行 Apache-Mina SSHD-Server (2.2.0)?
How to run an Apache-Mina SSHD-Server (2.2.0) on Android Pie?
我正尝试在 Android Pie (API 28.0) 设备上 运行 Apache MINA SSHD 服务器 (v. 2.2.0)。我在 Android 4 台设备上 运行ning 发现了各种 post,但其中 none 似乎可以在我的 Android 9 设备上运行。所以我尝试自己实现它,但在使用 ReflectionException/NoClassDefFoundError.
初始化服务器时卡住了
当我尝试使用 SshServer.setUpDefaultServer() 设置服务器时;我得到这个例外:
java.lang.NoClassDefFoundError: Failed resolution of: Ljavax/management/ReflectionException;
at org.apache.sshd.common.util.GenericUtils.peelException(GenericUtils.java:730)
at org.apache.sshd.common.util.GenericUtils.peelException(GenericUtils.java:728)
at org.apache.sshd.common.util.security.SecurityEntityFactory.getInstance(SecurityEntityFactory.java:134)
at org.apache.sshd.common.util.security.SecurityUtils.getMessageDigest(SecurityUtils.java:726)
at org.apache.sshd.common.digest.DigestUtils.checkSupported(DigestUtils.java:53)
at org.apache.sshd.common.digest.BuiltinDigests.<init>(BuiltinDigests.java:61)
at org.apache.sshd.common.digest.BuiltinDigests.<clinit>(BuiltinDigests.java:36)
at org.apache.sshd.common.cipher.ECCurves.<clinit>(ECCurves.java:61)
at org.apache.sshd.common.keyprovider.KeyPairProvider.<clinit>(KeyPairProvider.java:63)
at org.apache.sshd.common.signature.BuiltinSignatures.<clinit>(BuiltinSignatures.java:62)
at org.apache.sshd.common.BaseBuilder.<clinit>(BaseBuilder.java:133)
at org.apache.sshd.server.ServerBuilder.builder(ServerBuilder.java:165)
at org.apache.sshd.server.SshServer.setUpDefaultServer(SshServer.java:429)
at ch.zhaw.init.sshshell.SshShellService.<init>(SshShellService.java:20)
从一些较旧的 posts for Android 4 看来,这是一个已知问题,解决方案是将 $useLibrary 'org.apache.http.legacy' 添加到 gradle并添加到 manifest.xml。我这样做了,但仍然出现异常。
build.gradle 文件:
android {
compileSdkVersion 28
useLibrary 'org.apache.http.legacy'
...
}
dependencies {
...
implementation 'org.apache.sshd:sshd-core:2.2.0'
implementation 'org.slf4j:slf4j-simple:1.6.2'
implementation 'org.apache.mina:mina-core:2.1.2'
implementation "org.bouncycastle:bcprov-jdk16:1.46"
}
manifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ch.zhaw.init.sshshell">
<application
android:networkSecurityConfig="@xml/network_security_config">
<uses-library android:name="org.apache.http.legacy"
android:required="false" />
<service android:name=".SshShellService">
<intent-filter>
<action android:name="StartSshServer"/>
</intent-filter>
</service>
</application>
</manifest>
我的Java-代码:
import org.apache.sshd.server.SshServer;
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
private static final int PORT = 8022;
private final SshServer sshd = SshServer.setUpDefaultServer(); // Here I get the error
private final SimplePasswordAuthenticator passwordAuth = new SimplePasswordAuthenticator();
private final SimplePublicKeyAuthenticator publicKeyAuth = new SimplePublicKeyAuthenticator();
private final SimpleForwardingFilter forwardingFilter = new SimpleForwardingFilter();
似乎旧版本可以工作,但我搜索了几天,但没有找到任何最新版本的工作示例。有没有人有一个工作示例,其中 运行 是 Android 9 上最新版本的 Apache Mina SSHD (2.2.0)(无需对设备进行 root)?
或者如果没有,是否有用于 Android Pie 的替代 SSH 服务器(不是客户端 - 有很多)?
感谢您的帮助。
对于这个特定的失败,创建一个虚拟的 ReflectionException class (example) 就足够了。鉴于 class 甚至不存在,您自己的代码之外的任何东西都不会实例化它,因此 SSHD 的 instanceof ReflectionException
检查永远不会匹配,您不需要对其任何成员进行编程。
您还需要创建一个虚拟 MBeanException (example)。
由于 BouncyCastle 库导致的错误已被弃用为 android9(api 级别 28)。
您可以从 aosp 获取详细提示:http://androidxref.com/9.0.0_r3/xref/libcore/ojluni/src/main/java/sun/security/jca/Providers.java#548
https://android-developers.googleblog.com/2018/03/cryptography-changes-in-android-p.html
要解决这个问题,您可以按照以下步骤操作:
- 从系统默认卸载 BouncyCastleProvider
Security.removeProvider("BC");
- 安装新的“BC”自定义提供程序
Security.addProvider(new BouncyCastleProvider());
- 初始化你的 mina sshd 服务
SshServer sshd = SshServer.setUpDefaultServer();
sshd.setPort(ssdServerPort);
....
aosp 只是比较对象来决定 bc 提供者对象是否是系统默认提供者,所以只需替换为新的 bc 提供者对象
:http://androidxref.com/9.0.0_r3/xref/libcore/ojluni/src/main/java/sun/security/jca/Providers.java#341
注意:您必须使用 :Security.removeProvider("BC")
卸载提供程序,然后再安装提供程序
我正尝试在 Android Pie (API 28.0) 设备上 运行 Apache MINA SSHD 服务器 (v. 2.2.0)。我在 Android 4 台设备上 运行ning 发现了各种 post,但其中 none 似乎可以在我的 Android 9 设备上运行。所以我尝试自己实现它,但在使用 ReflectionException/NoClassDefFoundError.
初始化服务器时卡住了当我尝试使用 SshServer.setUpDefaultServer() 设置服务器时;我得到这个例外:
java.lang.NoClassDefFoundError: Failed resolution of: Ljavax/management/ReflectionException;
at org.apache.sshd.common.util.GenericUtils.peelException(GenericUtils.java:730)
at org.apache.sshd.common.util.GenericUtils.peelException(GenericUtils.java:728)
at org.apache.sshd.common.util.security.SecurityEntityFactory.getInstance(SecurityEntityFactory.java:134)
at org.apache.sshd.common.util.security.SecurityUtils.getMessageDigest(SecurityUtils.java:726)
at org.apache.sshd.common.digest.DigestUtils.checkSupported(DigestUtils.java:53)
at org.apache.sshd.common.digest.BuiltinDigests.<init>(BuiltinDigests.java:61)
at org.apache.sshd.common.digest.BuiltinDigests.<clinit>(BuiltinDigests.java:36)
at org.apache.sshd.common.cipher.ECCurves.<clinit>(ECCurves.java:61)
at org.apache.sshd.common.keyprovider.KeyPairProvider.<clinit>(KeyPairProvider.java:63)
at org.apache.sshd.common.signature.BuiltinSignatures.<clinit>(BuiltinSignatures.java:62)
at org.apache.sshd.common.BaseBuilder.<clinit>(BaseBuilder.java:133)
at org.apache.sshd.server.ServerBuilder.builder(ServerBuilder.java:165)
at org.apache.sshd.server.SshServer.setUpDefaultServer(SshServer.java:429)
at ch.zhaw.init.sshshell.SshShellService.<init>(SshShellService.java:20)
从一些较旧的 posts for Android 4 看来,这是一个已知问题,解决方案是将 $useLibrary 'org.apache.http.legacy' 添加到 gradle并添加到 manifest.xml。我这样做了,但仍然出现异常。
build.gradle 文件:
android {
compileSdkVersion 28
useLibrary 'org.apache.http.legacy'
...
}
dependencies {
...
implementation 'org.apache.sshd:sshd-core:2.2.0'
implementation 'org.slf4j:slf4j-simple:1.6.2'
implementation 'org.apache.mina:mina-core:2.1.2'
implementation "org.bouncycastle:bcprov-jdk16:1.46"
}
manifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ch.zhaw.init.sshshell">
<application
android:networkSecurityConfig="@xml/network_security_config">
<uses-library android:name="org.apache.http.legacy"
android:required="false" />
<service android:name=".SshShellService">
<intent-filter>
<action android:name="StartSshServer"/>
</intent-filter>
</service>
</application>
</manifest>
我的Java-代码:
import org.apache.sshd.server.SshServer;
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
private static final int PORT = 8022;
private final SshServer sshd = SshServer.setUpDefaultServer(); // Here I get the error
private final SimplePasswordAuthenticator passwordAuth = new SimplePasswordAuthenticator();
private final SimplePublicKeyAuthenticator publicKeyAuth = new SimplePublicKeyAuthenticator();
private final SimpleForwardingFilter forwardingFilter = new SimpleForwardingFilter();
似乎旧版本可以工作,但我搜索了几天,但没有找到任何最新版本的工作示例。有没有人有一个工作示例,其中 运行 是 Android 9 上最新版本的 Apache Mina SSHD (2.2.0)(无需对设备进行 root)?
或者如果没有,是否有用于 Android Pie 的替代 SSH 服务器(不是客户端 - 有很多)?
感谢您的帮助。
对于这个特定的失败,创建一个虚拟的 ReflectionException class (example) 就足够了。鉴于 class 甚至不存在,您自己的代码之外的任何东西都不会实例化它,因此 SSHD 的 instanceof ReflectionException
检查永远不会匹配,您不需要对其任何成员进行编程。
您还需要创建一个虚拟 MBeanException (example)。
由于 BouncyCastle 库导致的错误已被弃用为 android9(api 级别 28)。
您可以从 aosp 获取详细提示:http://androidxref.com/9.0.0_r3/xref/libcore/ojluni/src/main/java/sun/security/jca/Providers.java#548
https://android-developers.googleblog.com/2018/03/cryptography-changes-in-android-p.html
要解决这个问题,您可以按照以下步骤操作:
- 从系统默认卸载 BouncyCastleProvider
Security.removeProvider("BC");
- 安装新的“BC”自定义提供程序
Security.addProvider(new BouncyCastleProvider());
- 初始化你的 mina sshd 服务
SshServer sshd = SshServer.setUpDefaultServer();
sshd.setPort(ssdServerPort);
....
aosp 只是比较对象来决定 bc 提供者对象是否是系统默认提供者,所以只需替换为新的 bc 提供者对象 :http://androidxref.com/9.0.0_r3/xref/libcore/ojluni/src/main/java/sun/security/jca/Providers.java#341
注意:您必须使用 :Security.removeProvider("BC")
卸载提供程序,然后再安装提供程序