当前位置: 首页 > 知识库问答 >
问题:

SSH使用JSch和PEM私钥,而路由器使用openssl密钥

燕正卿
2023-03-14

我想在静态编程语言中使用JSch通过SSH连接到我的OpenWRT路由器,带有SSL密钥。OpenWRT支持用ssh-keygen(https://openwrt.org/docs/guide-user/security/dropbear.public-key.auth)生成的密钥。

ssh-keygen -t rsa -b 4096

这将生成一个公共id_rsa。pub和private id_rsa密钥。OpenWRT接受这个id_rsa。酒吧我希望JSch使用私钥:

private fun sshCommand(
            username: String? = "root",
            host: String? = "192.168.1.1",
            port: Int = 22,
            command: String?
    ) {
        GlobalScope.launch(Dispatchers.IO) {
            var session: Session? = null
            var channel: ChannelExec? = null

            val privateKey: String = "-----BEGIN OPENSSH PRIVATE KEY-----\n" +
                    "...\n" +
                    "...\n" +
                    "-----END OPENSSH PRIVATE KEY-----"

            try {
                JSch().addIdentity("name", privateKey.toByteArray(), null, null)
                session = JSch().getSession(username, host, port)
                session.setConfig("PreferredAuthentications", "publickey");
                session.setConfig("StrictHostKeyChecking", "no")
                session.connect()
                channel = session.openChannel("exec") as ChannelExec
                channel.setCommand(command)
                val responseStream = ByteArrayOutputStream()
                channel.outputStream = responseStream
                channel.connect()
                while (channel.isConnected) {
                    Thread.sleep(100)
                }
                val responseString = String(responseStream.toByteArray())
                println(responseString)
            } finally {
                session?.disconnect()
                channel?.disconnect()
            }
        }
    }

但是,这给出了一个错误:

com.jcraft.jsch.JSchException: invalid privatekey: [B@6166596

JSch不支持这种密钥格式,它必须是PEM。所以我转换私钥:

-----BEGIN RSA PRIVATE KEY-----
.
.
.
-----END RSA PRIVATE KEY-----

但现在的错误是:

com.jcraft.jsch.JSchException: Auth fail

OpenWRT上的公钥和JSch中的私钥的格式是否不同?

编辑2013年2月21日:我添加了这一行:

session.setConfig("PreferredAuthentications", "publickey");

我还使用此代码向JSch添加了记录器,这是输出:

W/System.err: INFO: Connecting to 192.168.1.1 port 22
W/System.err: INFO: Connection established
W/System.err: INFO: Remote version string: SSH-2.0-dropbear
W/System.err: INFO: Local version string: SSH-2.0-JSCH-0.1.54
    INFO: CheckCiphers: aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,3des-ctr,arcfour,arcfour128,arcfour256
D/EGL_emulation: eglMakeCurrent: 0xf0a7ee60: ver 3 0 (tinfo 0xf0aca800)
D/EGL_emulation: eglMakeCurrent: 0xf0a7ee60: ver 3 0 (tinfo 0xf0aca800)
W/System.err: INFO: CheckKexes: diffie-hellman-group14-sha1,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521
W/System.err: INFO: CheckSignatures: ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521
W/System.err: INFO: SSH_MSG_KEXINIT sent
W/System.err: INFO: SSH_MSG_KEXINIT received
W/System.err: INFO: kex: server: curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,kexguess2@matt.ucc.asn.au
W/System.err: INFO: kex: server: ssh-rsa
W/System.err: INFO: kex: server: aes128-ctr,aes256-ctr
W/System.err: INFO: kex: server: aes128-ctr,aes256-ctr
W/System.err: INFO: kex: server: hmac-sha1,hmac-sha2-256
W/System.err: INFO: kex: server: hmac-sha1,hmac-sha2-256
    INFO: kex: server: none
W/System.err: INFO: kex: server: none
W/System.err: INFO: kex: server: 
    INFO: kex: server: 
W/System.err: INFO: kex: client: ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1
W/System.err: INFO: kex: client: ssh-rsa,ssh-dss,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521
W/System.err: INFO: kex: client: aes128-ctr,aes128-cbc,3des-ctr,3des-cbc,blowfish-cbc,aes192-ctr,aes192-cbc,aes256-ctr,aes256-cbc
W/System.err: INFO: kex: client: aes128-ctr,aes128-cbc,3des-ctr,3des-cbc,blowfish-cbc,aes192-ctr,aes192-cbc,aes256-ctr,aes256-cbc
W/System.err: INFO: kex: client: hmac-md5,hmac-sha1,hmac-sha2-256,hmac-sha1-96,hmac-md5-96
W/System.err: INFO: kex: client: hmac-md5,hmac-sha1,hmac-sha2-256,hmac-sha1-96,hmac-md5-96
W/System.err: INFO: kex: client: none
W/System.err: INFO: kex: client: none
    INFO: kex: client: 
W/System.err: INFO: kex: client: 
W/System.err: INFO: kex: server->client aes128-ctr hmac-sha1 none
W/System.err: INFO: kex: client->server aes128-ctr hmac-sha1 none
W/System.err: INFO: SSH_MSG_KEXDH_INIT sent
W/System.err: INFO: expecting SSH_MSG_KEXDH_REPLY
W/System.err: INFO: ssh_rsa_verify: signature true
W/System.err: WARN: Permanently added '192.168.1.1' (RSA) to the list of known hosts.
W/System.err: INFO: SSH_MSG_NEWKEYS sent
W/System.err: INFO: SSH_MSG_NEWKEYS received
W/System.err: INFO: SSH_MSG_SERVICE_REQUEST sent
W/System.err: INFO: SSH_MSG_SERVICE_ACCEPT received
W/System.err: INFO: Authentications that can continue: publickey
    INFO: Next authentication method: publickey
W/System.err: INFO: Disconnecting from 192.168.1.1 port 22
E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-1
    Process: com.example.ps4nuker, PID: 30981
    com.jcraft.jsch.JSchException: Auth fail
        at com.jcraft.jsch.Session.connect(Session.java:519)
        at com.jcraft.jsch.Session.connect(Session.java:183)
        at com.example.ps4nuker.MainActivity$sshCommand$1.invokeSuspend(MainActivity.kt:113)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
        at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
I/Process: Sending signal. PID: 30981 SIG: 9
Disconnected from the target VM, address: 'localhost:56256', transport: 'socket'

这是OpenWRT路由器上的日志(最高日志级别):

Sat Feb 13 15:47:51 2021 authpriv.info dropbear[7783]: Child connection from 192.168.1.23:56269
Sat Feb 13 15:47:52 2021 authpriv.info dropbear[7783]: Exit before auth (user 'root', 0 fails): Disconnect received

相同的OpenWRT日志,当连接到SSH使用相同的私钥:

Thu Feb 18 00:24:51 2021 authpriv.info dropbear[17648]: Child connection from 192.168.1.23:50127
Thu Feb 18 00:24:52 2021 authpriv.notice dropbear[17648]: Pubkey auth succeeded for 'root' with key sha1!! 85:eb:c4:d2:dd:d9:15:d3:ee:29:3a:80:df:48:8f:6c:41:73:a8:5e from 192.168.1.23:50127

共有1个答案

单喜
2023-03-14

您有两个Jsch实例,因此会话不会获得您添加到另一个实例的标识

val jSch = JSch()
jSch.addIdentity("blabla123", privateKey.toByteArray(), null, null)
session = jSch.getSession(username, host, port)
 类似资料:
  • 我正在尝试使用openssl生成一个安全的私钥和公钥,以便与我的云托管提供商一起使用,但当我这样做时,openssl的公钥输出未被识别。 生成RSA私钥后,2048位长模,然后 它编写了RSA公钥。输出如下所示: 这是标准格式,它非常适合其他用途,但所有云和托管服务提供商都需要这样的公钥: 这是他们识别的唯一有效格式。 我知道ssh-keygen可以轻松完成所有这些,但我正在使用当前最新的open

  • 问题内容: 我有一个加密的私钥,并且知道密码。 我需要使用Java库对其进行解密。 不过,我宁愿不要使用BouncyCastle,除非没有其他选择。根据以前的经验,有太多更改,没有足够的文档。 私钥的格式如下: 我相信关键数据是Base64编码的,因为我看到的是64个字符。 我尝试了以下解密密钥: 我得到这个例外 我是否将正确的参数传递给构造函数? 我该如何工作? 我尝试了Ericsonn的建议,

  • 我有一个加密的私钥,我知道密码。 我需要用Java库解密它。 不过,我不想使用BouncyCastle,除非没有其他选择。根据之前的经验,变更太多,文档不足。 私钥的格式如下: 我相信密钥数据是Base64编码的,因为我在64个字符后看到。 我尝试了以下方法来解密密钥: 我得到这个例外 我是否将正确的参数传递给构造函数? 我怎样才能做到这一点? 我尝试了Ericsonn的建议,有一个小的变化,因为

  • 我想使用带有RSA算法的OpenSSL使用私钥加密文件: 现在,如果我执行解密操作: 此操作需要私钥 我知道我应该使用公钥进行加密,如果我使用私钥,我会得到一个签名。 然而,我想这样做是为了学习。

  • 问题内容: 我正在尝试使用Go编程语言的[ssh] [1]包通过密钥连接到Amazon AWS AWS Linux服务器。但是,软件包文档有些含糊/令人困惑。有谁知道如何通过使用密钥的ssh进行连接,或者至少在可能的情况下?令我困扰的是[Dial] [3]示例中的内容 我基本上想模仿ssh -i x.pem root@server.com的行为,并在服务器内部执行命令(例如) 问题答案: 您需要使

  • 问题内容: 我正在使用以下代码在Java应用程序中使用Git。我有一个有效的密钥(一直使用),并且之前使用相同的密钥和git存储库,此特定代码对我有用,但是现在出现以下异常: 无效的私钥:[B @ 59c40796。 在这一行: 我的完整代码: 在线搜索后,我将createDefaultJSch更改为使用pemWriter: 但是仍然会收到 “无效的私钥” 异常。 问题答案: 我也偶然发现了这个问