9

I am attempting to connect to an SFTP server that requires private key authentication and wanting to use the Mina. Looking through the documentation, I can see how to perform that authentication using password authentication but not private key authentication. I do not see any example code that would demonstrate how to perform private key authentication using mina.

Is it currently possible with this library, and if so, can you provide an example code on how to load the key and perform the connection?

Here is an example of what I want to do using SSHTools for reference.

   private static void authenticate(Ssh2Client ssh2, String host, Integer port, String username, InputStream privateKey) {
    Ssh2PublicKeyAuthentication auth = createKeyAuthentication(privateKey);

    try {
        int result = ssh2.authenticate(auth);
        if (result != SshAuthentication.COMPLETE) {
            throw new AuthenticationIncomplete(host, port, username, result);
        }
    } catch (SshException ex) {
        throw new UnableToAuthenticate(host, port, username, ex);
    }
}

private static Ssh2PublicKeyAuthentication createKeyAuthentication(InputStream privateKey) {
    try {
        SshPrivateKeyFile privateKeyFile = SshPrivateKeyFileFactory.parse(StreamUtil.readIntoByteArray(privateKey));
        SshKeyPair keyPair = privateKeyFile.toKeyPair("");

        Ssh2PublicKeyAuthentication auth = new Ssh2PublicKeyAuthentication();
        auth.setPrivateKey(keyPair.getPrivateKey());
        auth.setPublicKey(keyPair.getPublicKey());
        return auth;
    } catch (IOException | InvalidPassphraseException ex) {
        throw new ConfigurationIssue(ex);
    }
}
Olaf Kock
  • 46,930
  • 8
  • 59
  • 90
Chuck Lowery
  • 902
  • 6
  • 17

3 Answers3

0

According to ClientSession documentation:

A client session is established using the SshClient. Once the session has been created, the user has to authenticate using either ClientAuthenticationManager.addPasswordIdentity(String) or ClientAuthenticationManager.addPublicKeyIdentity(java.security.KeyPair) followed by a call to auth()

So you may need to try something like this:

// path to your private key
Path privateKeyPath = Paths.get("/path/to/your/privatekey.pem");
        
// load the private key
FileKeyPairProvider fileKeyPairProvider = new FileKeyPairProvider(privateKeyPath);
Iterable<KeyPair> keyPairs = fileKeyPairProvider.loadKeys();

try (SshClient client = SshClient.setUpDefaultClient()) {
    client.start();

    try (ClientSession session = client.connect("username", "hostname", 22).verify().getSession()) {
        // authenticate using the private key
        session.addPublicKeyIdentity(keyPairs.iterator().next());

        // auth agent can be null
        session.auth().verify();

        ...
    }
} ...
Yahor Barkouski
  • 1,361
  • 1
  • 5
  • 21
-1

I found an example from integration test, hope this help

https://github.com/apache/mina-sshd/blob/master/sshd-core/src/test/java/org/apache/sshd/client/auth/pubkey/RSAVariantsAuthPublicKeyTest.java#L87

@BeforeClass
public static void setupClientAndServer() throws Exception {
    sshd = CoreTestSupportUtils.setupTestServer(RSAVariantsAuthPublicKeyTest.class);
    sshd.setSignatureFactories(RSA_FACTORIES);
    sshd.setKeyPairProvider(KEYS_PROVIDER);
    sshd.setPasswordAuthenticator(RejectAllPasswordAuthenticator.INSTANCE);
    sshd.setHostBasedAuthenticator(RejectAllHostBasedAuthenticator.INSTANCE);
    sshd.setPublickeyAuthenticator((username, key, session) -> {
        String keyType = KeyUtils.getKeyType(key);
        outputDebugMessage("authenticate(%s) keyType=%s session=%s", username, keyType, session);
        return KeyPairProvider.SSH_RSA.equals(keyType);
    });

    sshd.start();
    port = sshd.getPort();

    client = CoreTestSupportUtils.setupTestClient(RSAVariantsAuthPublicKeyTest.class);
    client.setServerKeyVerifier((session, peerAddress, key) -> {
        String keyType = KeyUtils.getKeyType(key);
        outputDebugMessage("verifyServerKey - keyType=%s session=%s", keyType, session);
        return KeyPairProvider.SSH_RSA.equals(keyType);
    });
    client.start();
}
vudangngoc
  • 128
  • 2
  • 6
-1

Mina SSHD supports authorized key authentication.

Example client setup

    KeyPairResourceLoader loader = SecurityUtils.getKeyPairResourceParser();
    Collection<KeyPair> keys = loader.loadKeyPairs(null, filePath, passwordProvider);

    // provide keys to client session
    try (ClientSession session = ...estblish initial session...) {
        for (KeyPair kp : keys) {
            session.addKeyIdentity(kp);
        }
        
        session.auth().await(...);
    }

See client setup

A more complete client setup example is provided here.

zaxishere
  • 164
  • 1
  • 7