-
Notifications
You must be signed in to change notification settings - Fork 605
Description
I'm debugging an application that uses sshj for connecting to other machines when given an ssh key pair. I uploaded a PKCS#8 encoded private key to this application, with which I verified I could manually authenticate to the other machines it manages through ssh (ssh -i ~/.ssh/mykey.pem node
). However, the sshj library failed to authenticate with this key with the following stacktrace:
net.schmizz.sshj.userauth.UserAuthException: Exhausted available authentication methods
at net.schmizz.sshj.SSHClient.auth(SSHClient.java:232)
at net.schmizz.sshj.SSHClient.auth(SSHClient.java:208)
at com.cloudera.server.cmf.node.NodeConfigurator.connect(NodeConfigurator.java:368)
at com.cloudera.server.cmf.node.NodeConfigurator.configure(NodeConfigurator.java:965)
at com.cloudera.server.cmf.node.NodeConfigurator.run(NodeConfigurator.java:1043)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: net.schmizz.sshj.userauth.UserAuthException: Problem getting public key from PKCS8KeyFile{resource=[PrivateKeyStringResource]}
at net.schmizz.sshj.userauth.method.KeyedAuthMethod.putPubKey(KeyedAuthMethod.java:46)
at net.schmizz.sshj.userauth.method.AuthPublickey.buildReq(AuthPublickey.java:62)
at net.schmizz.sshj.userauth.method.AuthPublickey.buildReq(AuthPublickey.java:81)
at net.schmizz.sshj.userauth.method.AbstractAuthMethod.request(AbstractAuthMethod.java:63)
at net.schmizz.sshj.userauth.UserAuthImpl.authenticate(UserAuthImpl.java:68)
at net.schmizz.sshj.SSHClient.auth(SSHClient.java:226)
... 9 more
Caused by: java.io.IOException: Could not read key pair from: [PrivateKeyStringResource]
at net.schmizz.sshj.userauth.keyprovider.PKCS8KeyFile.readKeyPair(PKCS8KeyFile.java:165)
at net.schmizz.sshj.userauth.keyprovider.PKCS8KeyFile.getPublic(PKCS8KeyFile.java:78)
at net.schmizz.sshj.userauth.method.KeyedAuthMethod.putPubKey(KeyedAuthMethod.java:44)
... 14 more
Right before that stacktrace is a debug message (which I believe should be a warning instead):
Expected PEMEncryptedKeyPair or PEMKeyPair, got: org.bouncycastle.asn1.pkcs.PrivateKeyInfo@d11392bd
This happens because my PKCS#8 private key contains the standard header of -----BEGIN PRIVATE KEY-----
, which bouncycastle's openssl library parses into a PrivateKeyInfo object. As it is currently, sshj will only properly construct a PKCS8KeyFile
from a PEMEncryptedKeyPair
or PEMKeyPair
(as explained in the debug/warning message), which will only be returned from files with the -----BEGIN RSA PRIVATE KEY-----
header and correspond to PKCS#1 encoded files. Thus, it appears like the PKCS8KeyFile
will actually only work with PKCS#1 keys.
I believe it should still be possible to construct the PKCS#8 object from the PrivateKeyInfo
object that the openssl library returns. The object should contain the modulus and public exponent needed to reconstruct the public key for the key pair.