签名长度不正确:得到127但是期待128 [英] Signature length not correct: got 127 but was expecting 128

查看:218
本文介绍了签名长度不正确:得到127但是期待128的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Java 1.8升级后面临一个奇怪的问题。我在我们的一个实用程序中使用jsch-0.1.54.jar从各个地方下载文件。这个特殊的实用程序使用了将近4 - 5年没有任何问题(当时jsch-0.1.48)。那时环境是java 1.6。最近我们升级到java 1.8,结果我们升级了这个特定的实用程序。现在我们遇到一个奇怪的问题,它偶尔会发生,大多数情况下文件的下载都是完美的。



错误日志

  INFO:SSH_MSG_KEXDH_INIT发送
INFO:期待SSH_MSG_KEXDH_REPLY
INFO:断开SRV2000端口22
2016-10-28 08:42 :18:0576 ERROR [main] net.AerisAbstractMethod - 无法打开连接
com.jcraft.jsch.JSchException:Session.connect:java.security.SignatureException:签名长度不正确:得到127但是期望128
at com.jcraft.jsch.Session.connect(Session.java:565)
at com.jcraft.jsch.Session.connect(Session.java:183)
at com.aeris。 net.AerisSFTPMethod.connectToServer(AerisSFTPMethod.java:65)
at com.aeris.net.AerisAbstractMethod.getListOfFiles(AerisAbstractMethod.java:143)
at com.aeris.worker.AerisUploaderDownloader.performUploadDownloadListing(AerisUploaderDownloader。 java:112)
at com.aeris.main.AerisCommonSftpUt ility.main(AerisCommonSftpUtility.java:102)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect .DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.simontuffs.onejar.Boot.run(Boot.java:340)
在com.simontuffs.onejar.Boot.main(Boot.java:166)

成功日志: (在大多数情况下它是成功的)

  INFO:SSH_MSG_KEXDH_INIT已发送
INFO:期待SSH_MSG_KEXDH_REPLY
信息:ssh_rsa_verify:signature true
WARN:永久性地将SRV2000(RSA)添加到已知主机列表中。
INFO:SSH_MSG_NEWKEYS发送
INFO:SSH_MSG_NEWKEYS收到
INFO:SSH_MSG_SERVICE_REQUEST发送
INFO:SSH_MSG_SERVICE_ACCEPT收到
INFO:可以继续的身份验证:publickey,password,keyboard-interactive
INFO:下一个身份验证方法:publickey
INFO:身份验证成功(publickey)。
2016-10-28 08:36:48:0794 INFO [main] net.AerisAbstractMethod - 会话连接到服务器
2016-10-28 08:36:48:0794 INFO [main] net。 AerisAbstractMethod - 打开SFTP频道..
2016-10-28 08:36:48:0810 INFO [main] net.AerisAbstractMethod - 通过频道连接到服务器。
2016-10-28 08:36:48:0857 INFO [main] net.AerisAbstractMethod - 连接成功。
2016-10-28 08:36:48:0857 INFO [main] net.AerisAbstractMethod - 更改为目录:C:/ interfaces / ib / wf / work
2016-10-28 08:36 :48:0888 INFO [main] net.AerisAbstractMethod - 启动文件远程目录列表:C:/ interfaces / ib / wf / work

0 Oct 28,2016 04:15 ./
0 2016年10月28日04:15 ../

我对Vandyke进行了全面分析( sftp软件提供商)但在那一端没有发现任何错误。我也尝试使用不同的工具sftp,但我没有收到任何错误。以下是连接SFTP服务器的代码段。任何人都可以帮忙吗?

  protected void connectToServer()抛出AerisConnectionException {
JSch jSch =(JSch) this.client;
try {

session = jSch.getSession(config.getUsername(),config.getRemoteserver(),config.getPort());
LOGGER.info(使用用户名创建SSH会话:+ config.getUsername()+服务器:+ config.getRemoteserver()+at PORT:+ config.getPort());
if(config.getAuth()。equalsIgnoreCase(PASSWD)|| config.getAuth()。equalsIgnoreCase(KEYPASS)){
LOGGER.info(设置密码......) ;
session.setPassword(config.getPassword());
}

属性jShconfig = new Properties();
jShconfig.put(StrictHostKeyChecking,no);
jShconfig.put(PreferredAuthentications,
publickey,password,keyboard-interactive);
jShconfig.put(LogLevel,VERBOSE);


LOGGER.info(将超时设置为+ config.getTimeOut());
session.setTimeout(config.getTimeOut()* 1000);
session.setConfig(jShconfig);

session.connect();
LOGGER.info(会话连接到服务器);
this.connected = true;

} catch(JSchException e){
LOGGER.error(无法打开连接,e);
抛出新的AerisConnectionException(无法打开连接。);
}

}


解决方案

虽然让堆栈跟踪确认会很好,但我敢打赌,服务器正在使用RSA主机密钥进行身份验证,并且在极少数情况下错误地修剪前导零。



由PKCS#1定义的RSA签名值(以及加密值), SSH使用(包括SSL在内的许多其他内容)需要编码为固定长度k的八位字节串,其等于编码模数所需的长度,或非正式'与模数相同的大小'。但是,由于基础数学值是一个很大的非负(也就是无符号)整数,特别是modexp(s,d,n),历史上一些实现省略了前导零八位字节 - 在将值视为时有效的省略整数 - 导致编码值有时短于应有的值。



RSA签名(或加密)值实际上是一个统一的随机值(1,n)中的数字。因此,当服务器使用的RSA密钥具有像此处的1024的圆形二进制大小时,此修整将在大约每200次随机发生一次,或者如果作为有符号数修剪则为400。 / p>

我不知道,但在测试中我确认(Oracle) Java 6确实接受 <$ c $的'短'值c>签名键入 RSA 或者实际使用的 SHA1withRSA ,这两者都意味着PKCS1-v1_5方案,但 Java 7和8抛出您看到的异常。
OTOH OpenSSH和PuTTY(也由WinSCP和FileZilla使用)确实接受'short'值,同时始终发送正确的长度值;这种波斯特利亚行为可能使得更难以检测到同伴以这种方式行为不端。 (注意:我检查了OpenSSH 5.5和7.3,这是我手边最早和最新的,但只有当前的PuTTY 0.67,因为这就是我保持在线状态。)



你可以尝试将服务器软件实现者指向已发布的标准,但它可能没有任何好处。你可以问jcraft特殊情况;对于mpint / ASN.1,他们已经在DSA和ECDSA案例中有逻辑,我可能认为这同样是丑陋的。
如果服务器有另一个(可用的)密钥,请通过配置server_host_key来包含 ssh-rsa - 最简单的只需获取现有/默认列表,拆分,删除ssh-rsa(并选中不清空)和重新加入,而不是通过列出今天的特定算法来混淆您的用户和/或(共)维护者。


I am facing a strange problem after java 1.8 upgrade. I am using jsch-0.1.54.jar in one of our utility programs to download files from various places. This particular utility was being used for almost 4-5 years without any problem(back then it jsch-0.1.48). At that time environment was java 1.6. Recently we upgraded to java 1.8 and as a result we upgraded this particular utility. Now we are encountering a strange problem and it occurs occasionally, and most of the time the download of files are prefect.

Error log

INFO: SSH_MSG_KEXDH_INIT sent
INFO: expecting SSH_MSG_KEXDH_REPLY
INFO: Disconnecting from SRV2000 port 22
2016-10-28 08:42:18:0576 ERROR  [main] net.AerisAbstractMethod - Failed to open connection 
com.jcraft.jsch.JSchException: Session.connect: java.security.SignatureException: Signature length not correct: got 127 but was expecting 128
    at com.jcraft.jsch.Session.connect(Session.java:565)
    at com.jcraft.jsch.Session.connect(Session.java:183)
    at com.aeris.net.AerisSFTPMethod.connectToServer(AerisSFTPMethod.java:65)
    at com.aeris.net.AerisAbstractMethod.getListOfFiles(AerisAbstractMethod.java:143)
    at com.aeris.worker.AerisUploaderDownloader.performUploadDownloadListing(AerisUploaderDownloader.java:112)
    at com.aeris.main.AerisCommonSftpUtility.main(AerisCommonSftpUtility.java:102)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.simontuffs.onejar.Boot.run(Boot.java:340)
    at com.simontuffs.onejar.Boot.main(Boot.java:166)

Success Log: (in most of the cases it is success)

INFO: SSH_MSG_KEXDH_INIT sent
INFO: expecting SSH_MSG_KEXDH_REPLY
INFO: ssh_rsa_verify: signature true
WARN: Permanently added 'SRV2000' (RSA) to the list of known hosts.
INFO: SSH_MSG_NEWKEYS sent
INFO: SSH_MSG_NEWKEYS received
INFO: SSH_MSG_SERVICE_REQUEST sent
INFO: SSH_MSG_SERVICE_ACCEPT received
INFO: Authentications that can continue: publickey,password,keyboard-interactive
INFO: Next authentication method: publickey
INFO: Authentication succeeded (publickey).
2016-10-28 08:36:48:0794 INFO   [main] net.AerisAbstractMethod - Session connected to server
2016-10-28 08:36:48:0794 INFO   [main] net.AerisAbstractMethod - Opening SFTP channel..
2016-10-28 08:36:48:0810 INFO   [main] net.AerisAbstractMethod - Connecting to server through channel.
2016-10-28 08:36:48:0857 INFO   [main] net.AerisAbstractMethod - Connection successful.
2016-10-28 08:36:48:0857 INFO   [main] net.AerisAbstractMethod - Changing to directory:C:/interfaces/ib/wf/work
2016-10-28 08:36:48:0888 INFO   [main] net.AerisAbstractMethod - Start file Listing of the remote directory:C:/interfaces/ib/wf/work

       0 Oct 28, 2016 04:15 ./
       0 Oct 28, 2016 04:15 ../

I did a complete analysis with Vandyke (sftp software provider) but did not find any error at that end. I also tried to sftp using different tools but I am not getting any error. Following is the code snippet to connect of SFTP server. Can any one help in this matter?

protected void connectToServer() throws AerisConnectionException {
        JSch jSch =(JSch)this.client;
        try {

            session = jSch.getSession(config.getUsername(), config.getRemoteserver(), config.getPort());
            LOGGER.info("Creating SSH Session using Username:"+config.getUsername()+ " Server :" +config.getRemoteserver()+ " at PORT:"+config.getPort());
            if(config.getAuth().equalsIgnoreCase("PASSWD")||config.getAuth().equalsIgnoreCase("KEYPASS")){
                LOGGER.info("Setting password ...");
                session.setPassword(config.getPassword());
            }

            Properties jShconfig = new Properties();            
            jShconfig.put("StrictHostKeyChecking", "no");
            jShconfig.put("PreferredAuthentications", 
                      "publickey,password,keyboard-interactive");
            jShconfig.put("LogLevel", "VERBOSE");


            LOGGER.info("Setting timeout to "+config.getTimeOut());
            session.setTimeout(config.getTimeOut()*1000);
            session.setConfig(jShconfig);           

            session.connect();
            LOGGER.info("Session connected to server");
            this.connected=true;

        } catch (JSchException e) {
            LOGGER.error("Failed to open connection ",e);
            throw new AerisConnectionException("Failed to open connection.");
        }

    }

解决方案

Although it would be nice to have the stacktrace to confirm, I'll bet the server is using an RSA 'host' key to authenticate and is wrongly 'trimming' leading zero in rare cases.

RSA signature values (and encrypted values also) defined by PKCS#1, which SSH uses (as do many other things including SSL), are required to be encoded as an octet string of fixed length 'k' equal to the length required to encode the modulus, or informally 'the same size as the modulus'. However, since the underlying mathematical value is a large nonnegative (aka unsigned) integer, specifically modexp(s,d,n), historically some implementations have omitted leading zero octets -- an omission which is valid when treating the value as an integer -- resulting in an encoded value that is sometimes shorter than it should be.

The RSA signature (or encrypted) value is effectively a uniform random number in (1,n). Thus when the RSA key used by the server has a 'round binary' size like 1024 as here, this trimming will happen approximately 1 in 200 times at random, or 400 if trimmed as a signed number.

I did not know, but on testing I confirm that (Oracle) Java 6 does accept such a 'short' value for Signature type RSA or as actually used here SHA1withRSA, both of which imply the PKCS1-v1_5 scheme, but Java 7 and 8 throw the exception you saw. OTOH both OpenSSH and PuTTY (also used by WinSCP and FileZilla) do accept 'short' values, while always sending correct length values; this Postelian behavior may make it more difficult to detect when a peer is misbehaving this way. (Note: I checked OpenSSH 5.5 and 7.3, the oldest and newest I have conveniently at hand, but only the current PuTTY 0.67 because that's all I keep online.)

You can try pointing the server software implementor to the published standards, but it may not do any good. You could ask jcraft to special-case this; they already have logic in the DSA and ECDSA cases for mpint/ASN.1 that I might argue is equally ugly. Or if the server has another (usable) key, request that by configuring "server_host_key" to NOT include ssh-rsa -- easiest just get the existing/default list, split, remove "ssh-rsa" (and check not empty) and rejoin, instead of possibly confusing your users and/or (co)maintainers by listing today's specific algorithms.

这篇关于签名长度不正确:得到127但是期待128的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆