Public RSA-key of host is not verified
See original GitHub issueI’m new to sshj and I try to solve the following problem of verifying the identity of the host to connect to. The host is an SSH server that only provides its public key using the ssh-rsa host key algorithm (and not the ssh-ed25519 algorithm, too).
I use the following code to do the verification:
PublicKey publicKey = new Buffer.PlainBuffer(Base64.decode(“…”)).readPublicKey(); sshClient.addHostKeyVerifier(SecurityUtils.getFingerprint(publicKey));
whereas “…” contains the public key that can be listed requested from the host using the command ssh-keyscan -t rsa <host>.
The SSHClient uses the default configuration.
If I run this code on my machine (in this case the target host is the localhost), I get the following exception:
ERROR n.s.s.t.KeyExchanger - Disconnecting because none of the configured Host key verifiers ([net.schmizz.sshj.transport.verification.FingerprintVerifier$1@73f0d46f]) could verify ‘ssh-ed25519’ host key with fingerprint ca:5f:e9:2b:79:58:5c:0e:a5:b3:28:b5:51:9a:54:d2 for localhost:22
ERROR n.s.s.t.TransportImpl - Dying because - Could not verify ssh-ed25519
host key with fingerprint ...
for localhost
on port 22
net.schmizz.sshj.transport.TransportException: Could not verify ssh-ed25519
host key with fingerprint ...
for localhost
on port 22
at net.schmizz.sshj.transport.KeyExchanger.verifyHost(KeyExchanger.java:211)
at net.schmizz.sshj.transport.KeyExchanger.handle(KeyExchanger.java:365)
at net.schmizz.sshj.transport.TransportImpl.handle(TransportImpl.java:503)
at net.schmizz.sshj.transport.Decoder.decodeMte(Decoder.java:159)
at net.schmizz.sshj.transport.Decoder.decode(Decoder.java:79)
at net.schmizz.sshj.transport.Decoder.received(Decoder.java:231)
at net.schmizz.sshj.transport.Reader.run(Reader.java:59)
ERROR n.s.c.Promise - <<kex done>> woke to: net.schmizz.sshj.transport.TransportException: [HOST_KEY_NOT_VERIFIABLE] Could not verify ssh-ed25519
host key with fingerprint ...
for localhost
on port 22
I wonder why sshj still wants to use ssh-ed25519 for verification as the method KeyType.fromKey(publicKey) prints ssh-rsa.
I know that I can use sshClient.addHostKeyVerifier(new PromiscuousVerifier()); to circumvent the problem, but that is not the solution I’m looking for.
So the question is how I can verify the host key if I only have an RSA ciphered public key of the host?
I found out, that if I use an explicit DefaultConfiguation like this: DefaultConfig defaultConfig = new DefaultConfig(); defaultConfig.setSignatureFactories(new SignatureRSA.Factory()); and pass this to the constructor of the SSHClient the exception disappears.
I do not understand why the default configuration which consists of several preregistered signature factories (and the factory above is already present) will not work as expected. I suppose that all registered signature factories are used to verify the hosts public key. To me this looks like an error.
BTW: I’m using version 0.27.0 of sshj.
Kind regards, Marcus
Issue Analytics
- State:
- Created 4 years ago
- Reactions:5
- Comments:9 (1 by maintainers)
Thank you @oakkitten for the explanations. It allowed me to limit to RSA and now it works.
This is makes it very hard to imagine using SSHJ in production. It seems the above solution is OBE, there is no DefaultConfig.setSignatureFactories now.
By looping threw making each type of key the first choice, I am able to connect to all the hosts I have tried so far. You have to do extra work to keep SSHJ from killing your thread.
This is in Scala, I’m sure you can figure out how to do the same in java.
Logging is LOUD! There are a lot of messages generated doing this, so logback.xml is worth while, even then some are ERRORs.