我正在尝试使用JSCH jar通过Java代码进行SFTP。使用的JSCH jar版本是0.1.55。在我们的pom.xml文件中的条目是
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
我尝试连接的服务器是通过AWS提供的VPC Interface端点服务公开的服务。尝试通过此VPC进行SFTP的客户端是EC2实例。
我遇到的错误是
com.jcraft.jsch.JSchException: Algorithm negotiation fail
at com.jcraft.jsch.Session.receive_kexinit(Session.java:590)
at com.jcraft.jsch.Session.connect(Session.java:320)
以前列出服务器和客户端上存在的不同算法的日志是
2019-03-14 08:50:54,501 INFO [main] Transporter - Remote version string: SSH-2.0-OpenSSH_7.4
2019-03-14 08:50:54,501 INFO [main] Transporter - Local version string: SSH-2.0-JSCH-0.1.54
2019-03-14 08:50:54,501 INFO [main] Transporter - CheckCiphers: aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,3des-ctr,arcfour,arcfour128,arcfour256
2019-03-14 08:50:54,547 INFO [main] Transporter - CheckKexes: diffie-hellman-group14-sha1,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521
2019-03-14 08:50:54,590 INFO [main] Transporter - ecdh-sha2-nistp256 is not available.
2019-03-14 08:50:54,590 INFO [main] Transporter - ecdh-sha2-nistp384 is not available.
2019-03-14 08:50:54,590 INFO [main] Transporter - ecdh-sha2-nistp521 is not available.
2019-03-14 08:50:54,590 INFO [main] Transporter - CheckSignatures: ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521
2019-03-14 08:50:54,592 INFO [main] Transporter - ecdsa-sha2-nistp256 is not available.
2019-03-14 08:50:54,593 INFO [main] Transporter - ecdsa-sha2-nistp384 is not available.
2019-03-14 08:50:54,593 INFO [main] Transporter - ecdsa-sha2-nistp521 is not available.
2019-03-14 08:50:54,593 INFO [main] Transporter - SSH_MSG_KEXINIT sent
2019-03-14 08:50:54,593 INFO [main] Transporter - SSH_MSG_KEXINIT received
2019-03-14 08:50:54,593 INFO [main] Transporter - kex: server: curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1
2019-03-14 08:50:54,593 INFO [main] Transporter - kex: server: ecdsa-sha2-nistp256,ssh-ed25519
2019-03-14 08:50:54,593 INFO [main] Transporter - kex: server: aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,arcfour
2019-03-14 08:50:54,594 INFO [main] Transporter - kex: server: aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,arcfour
2019-03-14 08:50:54,594 INFO [main] Transporter - kex: server: hmac-sha1,hmac-ripemd160
2019-03-14 08:50:54,594 INFO [main] Transporter - kex: server: hmac-sha1,hmac-ripemd160
2019-03-14 08:50:54,594 INFO [main] Transporter - kex: server: none,zlib@openssh.com
2019-03-14 08:50:54,594 INFO [main] Transporter - kex: server: none,zlib@openssh.com
2019-03-14 08:50:54,594 INFO [main] Transporter - kex: server:
2019-03-14 08:50:54,594 INFO [main] Transporter - kex: server:
2019-03-14 08:50:54,594 INFO [main] Transporter - kex: client: diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1
2019-03-14 08:50:54,594 INFO [main] Transporter - kex: client: ssh-rsa,ssh-dss
2019-03-14 08:50:54,594 INFO [main] Transporter - kex: client: aes128-ctr,aes128-cbc,3des-ctr,3des-cbc,blowfish-cbc,aes192-ctr,aes192-cbc,aes256-ctr,aes256-cbc
2019-03-14 08:50:54,594 INFO [main] Transporter - kex: client: aes128-ctr,aes128-cbc,3des-ctr,3des-cbc,blowfish-cbc,aes192-ctr,aes192-cbc,aes256-ctr,aes256-cbc
2019-03-14 08:50:54,594 INFO [main] Transporter - kex: client: hmac-md5,hmac-sha1,hmac-sha2-256,hmac-sha1-96,hmac-md5-96
2019-03-14 08:50:54,594 INFO [main] Transporter - kex: client: hmac-md5,hmac-sha1,hmac-sha2-256,hmac-sha1-96,hmac-md5-96
2019-03-14 08:50:54,595 INFO [main] Transporter - kex: client: none
2019-03-14 08:50:54,595 INFO [main] Transporter - kex: client: none
2019-03-14 08:50:54,595 INFO [main] Transporter - kex: client:
2019-03-14 08:50:54,595 INFO [main] Transporter - kex: client:
如上面的日志所示,VPC端点(服务器)上的HostKeyAlgorithms为: ecdsa-sha2-nistp256,ssh-ed25519 ,而EC2实例(客户端)上的HostKeyAlgorithms为: ssh-rsa,ssh-dss 。
由于服务器和客户端之间没有用于执行主机检查的通用算法,因此由于算法协商失败而失败。
已经尝试了安装JCE无限强度策略文件的最建议解决方案,但没有解决问题。我将JCE策略jar安装在EC2实例(客户端)上的 $ JAVA_HOME / jre / lib / security 位置。
有关使用JSCH进行SFTP以及在JSCH jar中进行进一步调试的代码的详细信息。
我运行了命令
ssh -Q key
以获得EC2实例(客户端)环境上可用的主机密钥算法。 (这样做是为了确认算法是否存在于环境中。)输出为
ssh-ed25519
ssh-ed25519-cert-v01@openssh.com
ssh-rsa
ssh-dss
ecdsa-sha2-nistp256
ecdsa-sha2-nistp384
ecdsa-sha2-nistp521
ssh-rsa-cert-v01@openssh.com
ssh-dss-cert-v01@openssh.com
ecdsa-sha2-nistp256-cert-v01@openssh.com
ecdsa-sha2-nistp384-cert-v01@openssh.com
ecdsa-sha2-nistp521-cert-v01@openssh.com
创建了一个com.jcraft.jsch.Session对象 mSession ,在调用 mSession.connect(int timeOut)之前,我打印了存在于配置中的HostKeyAlgorithms mSession对象使用
mSession.getConfig("server_host_key")
输出为
ssh-rsa,ssh-dss,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521
在mSession.connect()调用(此函数调用位于JSCH jar内)内,进行了一个函数调用 this.send_kexinit()。在此send_kexinit()函数内部,以下代码是用于设置最终HostKeyAlgorithms的代码。
String server_host_key = this.getConfig("server_host_key");
String[] not_available_shks = this.checkSignatures(this.getConfig("CheckSignatures"));
if (not_available_shks != null && not_available_shks.length > 0) {
server_host_key = Util.diffString(server_host_key, not_available_shks);
if (server_host_key == null) {
throw new JSchException("There are not any available sig algorithm.");
}
}
checkSignatures()函数正在从列表 this.getConfig(“ CheckSignatures”)中检查算法列表,并检查它们是否存在。 checkSignatures()如下
private String[] checkSignatures(String sigs) {
if (sigs != null && sigs.length() != 0) {
if (JSch.getLogger().isEnabled(1)) {
JSch.getLogger().log(1, "CheckSignatures: " + sigs);
}
Vector result = new Vector();
String[] _sigs = Util.split(sigs, ",");
for(int i = 0; i < _sigs.length; ++i) {
try {
JSch var10000 = this.jsch;
Class c = Class.forName(JSch.getConfig(_sigs[i]));
Signature sig = (Signature)((Signature)c.newInstance());
sig.init();
} catch (Exception var7) {
result.addElement(_sigs[i]);
}
}
if (result.size() == 0) {
return null;
} else {
String[] foo = new String[result.size()];
System.arraycopy(result.toArray(), 0, foo, 0, result.size());
if (JSch.getLogger().isEnabled(1)) {
for(int i = 0; i < foo.length; ++i) {
JSch.getLogger().log(1, foo[i] + " is not available.");
}
}
return foo;
}
} else {
return null;
}
}
this.getConfig(“ CheckSignatures”)函数返回列表ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,并且在此列表上调用上述函数时,找不到算法,因为它们在日志中打印为
ecdsa-sha2-nistp256 is not available.
ecdsa-sha2-nistp384 is not available.
ecdsa-sha2-nistp521 is not available.
很明显,checkSignatures()函数中的try块是调用失败的地方,因此已将它们添加到不可用列表中。因此,这3种算法已从HostKeyAlgorithms列表中删除。因此
的列表this.getConfig("server_host_key")
经过checkSignatures()方法后只有
ssh-rsa,ssh-dss
我无法理解为什么try块失败,如com.jcraft.jsch.JSch.java文件中所示,在JSch类的配置中添加了以上3种算法。
config.put("CheckSignatures", "ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521");
config.put("signature.dss", "com.jcraft.jsch.jce.SignatureDSA");
config.put("signature.rsa", "com.jcraft.jsch.jce.SignatureRSA");
config.put("keypairgen.dsa", "com.jcraft.jsch.jce.KeyPairGenDSA");
config.put("keypairgen.rsa", "com.jcraft.jsch.jce.KeyPairGenRSA");
config.put("keypairgen.ecdsa", "com.jcraft.jsch.jce.KeyPairGenECDSA");
config.put("ecdsa-sha2-nistp256", "com.jcraft.jsch.jce.SignatureECDSA256");
config.put("ecdsa-sha2-nistp384", "com.jcraft.jsch.jce.SignatureECDSA384");
config.put("ecdsa-sha2-nistp521", "com.jcraft.jsch.jce.SignatureECDSA521");
config.put("server_host_key", "ssh-rsa,ssh-dss,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521");
以及名为 com.jcraft.jsch.jce.SignatureECDSA256 , com.jcraft.jsch.jce.SignatureECDSA384 和 com.jcraft.jsch的类。 jce.SignatureECDSA521 存在于jar文件内的相应位置。
所以我不清楚,即使JSCH jar中存在类并且在 $ JAVA_HOME /中安装了JCE无限强度策略文件,checkSignatures()函数中的try块为什么会失败? jre / lib / security 路径正确。 (安装的策略文件适用于JDK 1.8,因为我们使用的JDK版本是1.8)
谁能帮我理解为什么这些算法(ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521)(尤其是ecdsa-sha2-nistp256)并非如此可用。 (因为很明显,将ecdsa-sha2-nistp256添加到客户端的可用HostKeyAlgorithms列表将为服务器和客户端进行协商提供通用的算法。)
编辑:
当我们通过在sshd_config文件中添加以下行并重新启动sshd服务在服务器端添加密钥交换算法时,此问题已解决。
KexAlgorithms ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1
添加算法ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521
时出现错误
ecdsa-sha2-nistp256 is not available.
ecdsa-sha2-nistp384 is not available.
ecdsa-sha2-nistp521 is not available.
走开。仍在研究这些密钥交换算法和HostKey算法之间的关系。