0

我正在尝试在 Android Pie (API 28.0) 设备上运行 Apache MINA SSHD 服务器 (v. 2.2.0)。我发现了各种关于它在 Android 4 设备上运行的帖子,但它们似乎都不能在我的 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$2.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)

从 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"
}

清单.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 服务器(不是客户端 - 有很多)?

感谢您的任何帮助。

4

2 回答 2

0

对于这个特定的故障,创建一个虚拟 ReflectionException 类(示例)就足够了。鉴于该类甚至不存在,您自己的代码之外的任何内容都不会实例化它,因此 SSHD 的instanceof ReflectionException检查永远不会匹配,并且您不需要对其任何成员进行编程。

您还需要创建一个虚拟 MBeanException (example)

于 2020-01-21T20:56:29.283 回答
0

由于 BouncyCastle lib 导致的错误已被弃用为 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

要解决此问题,您可以按照以下步骤操作:

  1. 从系统默认卸载 BouncyCastleProvider
Security.removeProvider("BC");
  1. 安装新的“BC”自定义提供程序
Security.addProvider(new BouncyCastleProvider());
  1. 初始化你的 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/安全/jca/Providers.java#341

注意:Security.removeProvider("BC")在安装提供程序之前,您必须使用 : 卸载提供程序

于 2021-07-05T05:30:22.803 回答