spring-integration-sftp v6.1.2 throws "Server key did not validate"

228 views Asked by At

I upgraded spring-integration-sftp from 5.2.3 RELEASE to v6.1.2 and injected a sshclient into DefaultSftpSessionFactory during session creation. I got "SshException: Server key did not validate". I believe this is known_hosts issue because if serverKeyVerified is set as AcceptAllServerKeyVerifier.INSTANCE (not using known_hosts), the app does not use known_hosts and works without error. The known_hosts file (/known_hosts/sfeg-public-key) is the same as the old working version, so something is wrong in coding? thanks!

Private key: /known_hosts/sfeg-private-key (1678 bytes)

-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAosLaHA9mGBZrISlSp4u5xYsHAoa/jnqt1hUCmVBccfywTZiI
yvkE7y+QHhU1oYpCyAOXSojIIpTnOYhUsJHuB9hyLsnmNWWr2pnydyayRuj9gvsO
<......  ommitt 21 lines .............>
3rLna1UdXUVuO/KctuYdom5Ii2BAdIba7FRMRH9OuEkHbb3CNXADKkAbs7eTCNcY
i+4GBBKBJjP8EXdtIwc3Wf0OlPf4O2i0hQojYf8WUsHwWrZJ5LqMiw==
-----END RSA PRIVATE KEY-----

Known Hosts: /known_hosts/sfeg-public-key

sfeg.test.ag.test.group.ca,172.64.41.187 ssh-rsa AAAAB3NzaC<....ommitted....>th0Oqdc=

Coding (some were from spring-intergration-sftp-6.1.2 org.springframework.integration.sftp.session.doInitInnerClient()):

   @Bean
    
        public SessionFactory<SftpClient.DirEntry> sftpSessionFactory() throws InvalidConfigException, IOException {
        
        
            SshClient sshClient = SshClient.setUpDefaultClient();
            sshClient.setKeyExchangeFactories(NamedFactory.setUpTransformedFactories(
                    false,
                    BuiltinDHFactories.VALUES,
                    ClientBuilder.DH2KEX
            ));
        
            boolean isAllowUnknownKeys = properties.isAllowUnknownKeys();
        
            sshClient.setSignatureFactories(new ArrayList<>(BuiltinSignatures.VALUES));
        
            ServerKeyVerifier serverKeyVerifier =
                    isAllowUnknownKeys ? AcceptAllServerKeyVerifier.INSTANCE : RejectAllServerKeyVerifier.INSTANCE;
        
            if (!isAllowUnknownKeys) {
                String knownHostFileStr = properties.getKnownHostFile();
                if (StringUtils.isBlank(knownHostFileStr))
                    throw new KnownHostFileNotDefinedException("Must define known_hosts file when allow-unknown-keys is false. ");
        
                File knownHostFile = new File(knownHostFileStr);
                if (!knownHostFile.exists())
                    throw new KnownHostFileNotFoundException("Cannot find known_hosts file when allow-unknown-keys is false.");
        
                logger.info("SFTP Known Hosts");
// properties.getKnownHostFile() -> "/known_hosts/sfeg-public-key"
                Resource resource = resourceLoader.getResource("file:"+properties.getKnownHostFile());
                logger.info("SFTP Known Hosts: length = {}", resource.contentLength());
                logger.info("SFTP Known Hosts: content = {}", resource.getContentAsString(Charset.defaultCharset()));
        
                serverKeyVerifier = new ResourceKnownHostsServerKeyVerifier(resource);
            }
        
            sshClient.setServerKeyVerifier(serverKeyVerifier);
            sshClient.setPasswordIdentityProvider(PasswordIdentityProvider.wrapPasswords(properties.getPassword()));
        
            if (properties.getSshPrivateKey() != null) {
                if(!(new File(properties.getSshPrivateKey()).exists()))
                    throw new KnownHostFileNotDefinedException("Cannot find known_hosts file private key file. ");
        
                logger.info("SFTP Configuration: setPrivateKey");
                Resource resource = resourceLoader.getResource("file:"+properties.getSshPrivateKey());;
                logger.info("SFTP Configuration: privateKey - length {}", resource.contentLength());
                logger.info("SFTP Configuration: privateKey - content {}", resource.getContentAsString(Charset.defaultCharset()));
        
                IoResource<Resource> privateKeyResource =
                        new AbstractIoResource<>(Resource.class, resource) {
        
                            @Override
                            public InputStream openInputStream() throws IOException {
                                return getResourceValue().getInputStream();
                            }
        
                        };
                try {
                    Collection<KeyPair> keys =
                            SecurityUtils.getKeyPairResourceParser()
                                    .loadKeyPairs(null, privateKeyResource,
                                            FilePasswordProvider.of(properties.getSshPrivatePassphrase()));
                    sshClient.setKeyIdentityProvider(KeyIdentityProvider.wrapKeyPairs(keys));
                }
                catch (GeneralSecurityException ex) {
                    throw new IOException("Cannot load private key: " + resource.getFilename(), ex);
                }
            }
        
            DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(sshClient, true);
        
            factory.setHost(properties.getHost());
            factory.setPort(properties.getPort());
            factory.setUser(properties.getUsername());
        
            CachingSessionFactory<SftpClient.DirEntry> cachingSessionFactory = new CachingSessionFactory<>(factory);
            this.properties.getServerAliveInterval().ifPresent(timeout -> cachingSessionFactory.setSessionWaitTimeout(timeout));
            return cachingSessionFactory;
        }

Logging:

2024-01-30 22:24:00.197 DEBUG 1 --- []-nio2-thread-2] [,] o.a.s.client.session.ClientSessionImpl   : encode(ClientSessionImpl[[email protected]/142.34.91.187:22]) packet #1 sending command=30[30] len=133
2024-01-30 22:24:00.197 DEBUG 1 --- []-nio2-thread-2] [,] o.a.sshd.common.io.nio2.Nio2Session      : writeBuffer(Nio2Session[local=/10.97.38.254:44294, remote=sfeg.test.ag..ca/142.34.91.187:22]) writing 152 bytes
2024-01-30 22:24:00.206 DEBUG 1 --- []-nio2-thread-1] [,] o.a.s.client.session.ClientSessionImpl   : doHandleMessage(ClientSessionImpl[[email protected]/142.34.91.187:22]) process #1 31
2024-01-30 22:24:00.207 DEBUG 1 --- []-nio2-thread-1] [,] org.apache.sshd.client.kex.DHGClient     : next(DHGClient[diffie-hellman-group1-sha1])[ClientSessionImpl[[email protected]/142.34.91.187:22]] process command=SSH_MSG_KEXDH_REPLY
2024-01-30 22:24:00.282 DEBUG 1 --- []-nio2-thread-1] [,] o.a.s.client.session.ClientSessionImpl   : setServerKey(ClientSessionImpl[[email protected]/142.34.91.187:22]) keyType=ssh-dss, digest=SHA256:20q6x+yl2wYUlt7cFEqziDKLra8z9v12jTxFscOE7Uc
2024-01-30 22:24:00.283 DEBUG 1 --- []-nio2-thread-1] [,] o.a.s.client.session.ClientSessionImpl   : handleKexMessage(ClientSessionImpl[[email protected]/142.34.91.187:22])[diffie-hellman-group1-sha1] KEX processing complete after cmd=31
2024-01-30 22:24:00.289 DEBUG 1 --- []-nio2-thread-1] [,] o.a.s.client.session.ClientSessionImpl   : checkKeys(ClientSessionImpl[[email protected]/142.34.91.187:22]) key=ssh-dss-SHA256:20q6x+yl2wYUlt7cFEqziDKLra8z9v12jTxFscOE7Uc, verified=false
2024-01-30 22:24:00.290 DEBUG 1 --- []-nio2-thread-1] [,] o.a.sshd.common.io.nio2.Nio2Session      : handleReadCycleFailure(Nio2Session[local=/10.97.38.254:44294, remote=sfeg.test.ag..ca/142.34.91.187:22]) SshException after 91798977 nanos at read cycle=3: Server key did not validate
2024-01-30 22:24:00.290 DEBUG 1 --- []-nio2-thread-1] [,] o.a.sshd.common.io.nio2.Nio2Session      : exceptionCaught(Nio2Session[local=/10.97.38.254:44294, remote=sfeg.test.ag..ca/142.34.91.187:22]) caught SshException[Server key did not validate] - calling handler
2024-01-30 22:24:00.290 DEBUG 1 --- []-nio2-thread-1] [,] o.a.s.client.session.ClientSessionImpl   : signalAuthFailure(ClientSessionImpl[[email protected]/142.34.91.187:22]) type=SshException, signalled=true, first=false: Server key did not validate
2024-01-30 22:24:00.291  WARN 1 --- []-nio2-thread-1] [,] o.a.s.client.session.ClientSessionImpl   : exceptionCaught(ClientSessionImpl[[email protected]/142.34.91.187:22])[state=Opened] SshException: Server key did not validate

org.apache.sshd.common.SshException: Server key did not validate
    at org.apache.sshd.client.session.AbstractClientSession.checkKeys(AbstractClientSession.java:629)
    at org.apache.sshd.common.session.helpers.AbstractSession.handleKexMessage(AbstractSession.java:726)
    at org.apache.sshd.common.session.helpers.AbstractSession.doHandleMessage(AbstractSession.java:590)
    at org.apache.sshd.common.session.helpers.AbstractSession.lambda$handleMessage$0(AbstractSession.java:522)
    at org.apache.sshd.common.util.threads.ThreadUtils.runAsInternal(ThreadUtils.java:68)
    at org.apache.sshd.common.session.helpers.AbstractSession.handleMessage(AbstractSession.java:521)
    at org.apache.sshd.common.session.helpers.AbstractSession.decode(AbstractSession.java:1639)
    at org.apache.sshd.common.session.helpers.AbstractSession.messageReceived(AbstractSession.java:482)
    at org.apache.sshd.common.session.helpers.AbstractSessionIoHandler.messageReceived(AbstractSessionIoHandler.java:64)
    at org.apache.sshd.common.io.nio2.Nio2Session.handleReadCycleCompletion(Nio2Session.java:407)
    at org.apache.sshd.common.io.nio2.Nio2Session$1.onCompleted(Nio2Session.java:380)
    at org.apache.sshd.common.io.nio2.Nio2Session$1.onCompleted(Nio2Session.java:375)
    at org.apache.sshd.common.io.nio2.Nio2CompletionHandler.lambda$completed$0(Nio2CompletionHandler.java:38)
    at java.base/java.security.AccessController.doPrivileged(Unknown Source)
    at org.apache.sshd.common.io.nio2.Nio2CompletionHandler.completed(Nio2CompletionHandler.java:37)
    at java.base/sun.nio.ch.Invoker.invokeUnchecked(Unknown Source)
    at java.base/sun.nio.ch.Invoker$2.run(Unknown Source)
    at java.base/sun.nio.ch.AsynchronousChannelGroupImpl$1.run(Unknown Source)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.base/java.lang.Thread.run(Unknown Source)
0

There are 0 answers