在Java中使用Jsch和Sshj的RSA SSH2私钥问题

时间:2015-12-31 03:22:33

标签: java ssh bouncycastle jsch sshj

这里我尝试连接到远程计算机以通过SFTP进行文件传输。我们在连接到远程计算机时使用基于RSA SSH2 key的身份验证。

我尝试用以下两种方法做到这一点,我面临两种方法的问题。

方法1:使用JSCH

JSch jSch = new JSch();
Session session=jSch.getSession(SFTPUSER,SFTPHOST,SFTPPORT);

//This is only for dev server in production will be removed
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);

//Facing issue with the below statement
jSch.addIdentity("/home/jbadmin/.ssh2/id_rsa_2048_a");

session.connect();
Channel channel = session.openChannel("sftp");
channel.connect();

-----------------
-----------------
if(channel!=null) channel.disconnect(); 
if(session!=null) session.disconnect();

例外:

com.jcraft.jsch.JSchException: invalid privatekey: [B@8c38a2
at com.jcraft.jsch.KeyPair.load(KeyPair.java:747)
at com.jcraft.jsch.KeyPair.load(KeyPair.java:561)
at com.jcraft.jsch.IdentityFile.newInstance(IdentityFile.java:40)
at com.jcraft.jsch.JSch.addIdentity(JSch.java:407)
at com.jcraft.jsch.JSch.addIdentity(JSch.java:367)

方法2:使用SSHJ

SSHClient ssh = new SSHClient(); 
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
ssh.addHostKeyVerifier(new PromiscuousVerifier());
ssh.connect(SFTPHOST,SFTPPORT);

//Facing issue with below statements
OpenSSHKeyFile sshKeyFile = new OpenSSHKeyFile();
sshKeyFile.init("/home/jbadmin/.ssh2/id_rsa_2048_a");
ssh.authPublickey(SFTPUSER,sshKeyFile);

SFTPClient sftp = ssh.newSFTPClient();

-------------------------------------
-------------------------------------
sftp.close();
ssh.disconnect();
ssh.close();

异常(不使用BouncyCastle):

INFO  [net.schmizz.sshj.common.SecurityUtils] (http-localhost/127.0.0.1:8080-6) BouncyCastle not registered, using the default JCE provider
WARN  [net.schmizz.sshj.DefaultConfig] (http-localhost/127.0.0.1:8080-6) Disabling high-strength ciphers: cipher strengths apparently limited by JCE policy
INFO  [net.schmizz.sshj.transport.TransportImpl] (http-localhost/127.0.0.1:8080-6) Client identity string: SSH-2.0-SSHJ_0_9_0
INFO  [net.schmizz.sshj.transport.TransportImpl] (http-localhost/127.0.0.1:8080-6) Server identity string: SSH-2.0-6.4.6.215 SSH Tectia Server
WARN  [net.schmizz.sshj.userauth.keyprovider.OpenSSHKeyFile] (http-localhost/127.0.0.1:8080-6) Error reading public key: net.schmizz.sshj.common.Buffer$BufferException: Underflow
INFO  [net.schmizz.sshj.transport.TransportImpl] (http-localhost/127.0.0.1:8080-6) Disconnected - BY_APPLICATION
ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/sgiserve].[mvc]] (http-localhost/127.0.0.1:8080-6) JBWEB000236: Servlet.service() for servlet mvc threw exception: java.lang.VerifyError: (class: org/bouncycastle/openssl/PEMReader$EncryptedPrivateKeyParser, method: parseObject signature: (Lorg/bouncycastle/util/io/pem/PemObject;)Ljava/lang/Object;) Incompatible argument to function
   at org.bouncycastle.openssl.PEMReader.<init>(Unknown Source) [bcpkix-jdk15on-1.49.jar:1.49.0]
   at org.bouncycastle.openssl.PEMReader.<init>(Unknown Source) [bcpkix-jdk15on-1.49.jar:1.49.0]
   at org.bouncycastle.openssl.PEMReader.<init>(Unknown Source) [bcpkix-jdk15on-1.49.jar:1.49.0]
   at net.schmizz.sshj.userauth.keyprovider.PKCS8KeyFile.readKeyPair(PKCS8KeyFile.java:128) [sshj-0.9.0.jar:]
   at net.schmizz.sshj.userauth.keyprovider.PKCS8KeyFile.getPublic(PKCS8KeyFile.java:72) [sshj-0.9.0.jar:]
   at net.schmizz.sshj.userauth.keyprovider.OpenSSHKeyFile.getPublic(OpenSSHKeyFile.java:60) [sshj-0.9.0.jar:]
   at net.schmizz.sshj.userauth.method.KeyedAuthMethod.putPubKey(KeyedAuthMethod.java:44) [sshj-0.9.0.jar:]
   at net.schmizz.sshj.userauth.method.AuthPublickey.buildReq(AuthPublickey.java:62) [sshj-0.9.0.jar:]
   at net.schmizz.sshj.userauth.method.AuthPublickey.buildReq(AuthPublickey.java:81) [sshj-0.9.0.jar:]
   at net.schmizz.sshj.userauth.method.AbstractAuthMethod.request(AbstractAuthMethod.java:63) [sshj-0.9.0.jar:]
   at net.schmizz.sshj.userauth.UserAuthImpl.authenticate(UserAuthImpl.java:68) [sshj-0.9.0.jar:]
   at net.schmizz.sshj.SSHClient.auth(SSHClient.java:211) [sshj-0.9.0.jar:]
   at net.schmizz.sshj.SSHClient.authPublickey(SSHClient.java:316) [sshj-0.9.0.jar:]
   at net.schmizz.sshj.SSHClient.authPublickey(SSHClient.java:335) [sshj-0.9.0.jar:]

异常(使用BouncyCastle):

INFO  [net.schmizz.sshj.common.SecurityUtils] (http-/10.92.141.78:28080-1) BouncyCastle already registered as a JCE provider
WARN  [net.schmizz.sshj.DefaultConfig] (http-/10.92.141.78:28080-1) Disabling high-strength ciphers: cipher strengths apparently limited by JCE policy
INFO  [net.schmizz.sshj.transport.TransportImpl] (http-/10.92.141.78:28080-1) Client identity string: SSH-2.0-SSHJ_0_9_0
INFO  [net.schmizz.sshj.transport.TransportImpl] (http-/10.92.141.78:28080-1) Server identity string: SSH-2.0-6.4.6.215 SSH Tectia Server
ERROR [net.schmizz.sshj.transport.TransportImpl] (reader) Dying because - {}: net.schmizz.sshj.transport.TransportException: Unable to reach a settlement: [] and [aes256-cbc, aes192-cbc, aes128-cbc, aes256-ctr, aes192-ctr, aes128-ctr, 3des-cbc, seed-cbc@ssh.com]
    at net.schmizz.sshj.transport.Proposal.firstMatch(Proposal.java:165) [sshj-0.9.0.jar:]
    at net.schmizz.sshj.transport.Proposal.negotiate(Proposal.java:147) [sshj-0.9.0.jar:]
    at net.schmizz.sshj.transport.KeyExchanger.gotKexInit(KeyExchanger.java:239) [sshj-0.9.0.jar:]

我的私钥(id_rsa_2048_a):

$ cat id_rsa_2048_a
---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----
Subject: xxxxx
Comment: "2048-bit rsa, xxxxx@xxxxx, Tue Dec 29 2015 11:38:\47 +0800"
------------------------
------------------------
---- END SSH2 ENCRYPTED PRIVATE KEY ----

我的公钥(id_rsa_2048_a.pub):

$cat id_rsa_2048_a.pub
---- BEGIN SSH2 PUBLIC KEY ----
Subject: xxxxxx
Comment: "2048-bit rsa, xxxxx@xxxxxxx, Tue Dec 29 2015 11:38:\47 +0800"
---------------------
---------------------
---- END SSH2 PUBLIC KEY ----

授权文件:

key gwf.id_dsa_2048_a.pub
key id_rsa_2048_a.pub

我不确定我private key的问题或我实施的方式,我们已经将public key分享给了远程机器。使用putty,我们可以使用SCP将文件传输到远程计算机。

2 个答案:

答案 0 :(得分:1)

您似乎没有为JVM加载无限强度加密

WARN  [net.schmizz.sshj.DefaultConfig] (http-/10.92.141.78:28080-1) Disabling high-strength ciphers: cipher strengths apparently limited by JCE policy

请为您的JVM下载Java Cryptography Extensions,以便使用高强度密码和密钥。

答案 1 :(得分:1)

我有类似的问题,可能是您现有的私钥没有使用开放的SSH格式。 我的解决方案是使用以下命令转换现有的私钥文件:

ssh-keygen -i -f id_rsa_2048_a > id_rsa_2048_a_opensshformat