Using Mina SSHD (Client) to connect to SFTP using Private Key
Asked Answered
F

2

10

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);
    }
}
Freethinker answered 22/4, 2021 at 17:49 Comment(0)
C
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();

        ...
    }
} ...
Chelsea answered 30/6, 2023 at 16:4 Comment(0)
P
-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();
}
Privy answered 23/3, 2023 at 8:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.