我通过JSch验证了hostkey验证问题。我正在使用jsch 0.1.53,我的应用程序,我连接的服务器是SouthRiverTech的Titan SFTP服务器。
我尝试使用Puttygen,Titan内置密钥生成器以及JSch的内置库生成密钥对。我使用的设置是RSA,2048位。
JSch内置库创建的密钥似乎不起作用。 Titan和Puttygen生成的密钥能够与winSCP一起使用,但是不断给我一个JSch的“Reject Hostkey”错误,这应该是known_hosts文件的一个问题。根据我的发现,known_hosts文件应该与公钥文件相同,但请告诉我我是否错了。我已将Titan的SFTP版本设置为版本3.
我在Titan中为用户配置文件设置了相同的键,以找出错误所在的位置,但无济于事。到目前为止,我还没有在网上找到有关JSch和Titan服务器之间的hostkey问题的任何答案。这给我带来了巨大的麻烦。
提前感谢您提供的任何答案。我会尽力发布我可能错过的任何信息。
编辑
JSchException进一步调试:UnknownHostKey,然后是服务器使用的RSA密钥指纹。我的客户端密钥指纹和服务器密钥指纹是相同的,为什么会发生这种情况?
修改
这是我的Java代码:
knownHostsFile = "D:/Keys/test.pub";
privateKey = "D:/Keys/test";
Session session = null;
Channel channel = null;
for(int i = 0; i < 3; i++) {
try {
logger.debug("Starting Upload");
JSch ssh=new JSch();
logger.debug("setting hosts - public key");
ssh.setKnownHosts(knownHostsFile);
logger.debug("Known hosts set as "+knownHostsFile);
logger.debug("Setting identity - private key");
ssh.addIdentity(privateKey);
logger.debug("identity set");
try {
int hostSFTPPort = Integer.parseInt(sftpPort);
if (!hostUserName.equalsIgnoreCase("no")
&& !hostPassword.equalsIgnoreCase("no")
&& !hostAddress.equalsIgnoreCase("no")) {
session=ssh.getSession(hostUserName,hostAddress,hostSFTPPort);
session.setPassword(hostPassword);
}
} catch (NumberFormatException ef){
logger.debug(ef);
}
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "yes");
config.put("PreferredAuthentications", "publickey,keyboard-interactive,password");
session.setConfig(config);
logger.debug("Establishing connection...");
session.connect(120000);
logger.debug("Connection established.");
logger.debug("Creating SFTP Channel.");
channel=session.openChannel("sftp");
logger.debug("Channel assigned. Connecting channel...");
channel.connect(120000);
logger.debug("SFTP Channel created.");
ChannelSftp sftp = (ChannelSftp) channel;
logger.debug("connection:"+sftp.isConnected());
if(sftp.isConnected()) {
result=Constants.CONNECTION_ONLINE;
}
session.disconnect();
channel.disconnect();
break;
} catch (JSchException e) {
logger.debug(e);
logger.debug(session.getHost());
logger.debug(session.getHostKey());
logger.debug("Continuing next loop......");
throw new JSchException("Session.connect failed",e);
} catch (Exception ex) {
logger.debug(ex);
logger.debug("Continuing next loop......");
continue;
}
}
的图片
以下是我遇到问题的钥匙:
这个似乎不适用于winSCP,并且是在Linux环境中创建的
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA4R+w9rGUsBNJGZxAdnbnA7FMfGGhx3YaLYZtKf9wzKm8NkZeYIuh1fJ6ViX6RmdO55QxQ3PmBIg8QdhQ8m6SizEt9OGeXU2AnEbX/sbj54oHmiFsv24eDFzr7nrDKnrcllByob3LqjeOy5zg27kJt860oh6BAJfimdqVtETSXR1JHfqUIqGxIqsvyKEotX8gjoGkgsW653f18dW5PJKSEvrq6k1SL0bfgSAA0rN4nUq3JzDvowg5ijkOl91/lj8+FEQ7SjWmguTSx5BoI/CTxatCwNZSdzNED/u5A8I3716JuY7MEiTciPdzspGAXS2mHOtsDPkT7z6jvKQ6hWWv/w== test1@10.70.149.178
这个适用于winSCP,是在Windows环境中创建的
---- BEGIN SSH2 PUBLIC KEY ----
Comment: "test"
AAAAB3NzaC1yc2EAAAABJQAAAQEA9a1nnbl/DV2Zo7s1IUifeC5suRmdO2ikSb0ToteO9uvA
gg0zYKA1iH52ysC+4Ni86Ceal4oWGl1dXZRKOaWNH6175uDTI1aBfPBvOddBheTeSQAWOkaM
eL5PDDabLkaKZ1GrtbTeEFOD/Kj/dVREhT5/OcEdFmCbHK6+vr2klrtH2xOd/Qeb89BzDFaj
weNER3fFnHVqy5/Nugo3n7CsiBxuK8KOVN4WpDHzrVe/tjAfVZyH8l4XHlR7bWA5rlAGwt0Y
HILQ+lT1PRmi5PiDq7WuP7NF3QhWjG/D1u/5PC/DzxjTOxwwmXfYj2T2OkE/2/tHSdU4geYr
+1ivdASJ5w==
---- END SSH2 PUBLIC KEY ----
答案 0 :(得分:0)
您将帐户密钥对与主机密钥(对)混淆。
JSchException
“拒绝HostKey:...”表示服务器的公钥(也称为主机密钥)与您的代码已知或在{{缓存的公钥不同1}}文件。
服务器的主机密钥通常不是由PuTTYgen生成的(尽管可能是这样),并且肯定与WinSCP无关。在PuTTYgen中,您通常会生成一个帐户密钥对(然后可以在WinSCP中使用)。
有关详细信息,请参阅我的文章Understanding SSH key pairs。
帐户密钥对和主机密钥对彼此无关。无论您使用什么帐户密钥,它都不会使JSch接受服务器的主机密钥。忘了这个想法。这是完全错误的。
您必须在known_hosts
文件(或JSch known_hosts
接口的其他实现)中提供正确的主机密钥。您不能将HostKeyRepository
文件用于.pub
文件。 known_hosts
文件的设置格式如下:
known_hosts
您还可以使用IP_address ssh-rsa public_key
在运行时设置预期的主机密钥。