northshorefiend
northshorefiend

Reputation: 111

apache sshd public key authentication

I am trying to set up an ssh server using apache mina sshd. I want to use public key authentication, and basically I want to know how to implement

package org.apache.sshd.server;
import java.security.PublicKey;
import org.apache.sshd.server.session.ServerSession;

public interface PublickeyAuthenticator {

boolean authenticate(String username, PublicKey key, ServerSession session);

}

I see that what is passed is another public key. So I assume that you are supposed to compare the public key given in the param with the public key that the server has. But I don't know how to do that.

One thing I have found is this implementation. which seems pointless, as it seems to compare the modulus of the public key to itself. Assuming that this implementation has a bug, and should be comparing the moduli of each public key, is this enough for authentication - that the moduli agree? Surely if I just fed my publicly available public key to this function, then I would get authenticated?

Upvotes: 1

Views: 12336

Answers (2)

Sai Upadhyayula
Sai Upadhyayula

Reputation: 2496

The below code is an example of how to perform Public Key Authentication using Apache MINA SSHD, the example code creates a SFTP server.

import java.io.File;
import java.io.IOException;
import java.util.Collections;

@Service
public class MySftpServer {

    private Log log = LogFactory.getLog(MySftpServer.class);

    @PostConstruct
    public void startServer() throws IOException {
        start();
    }

    private void start() throws IOException {
        SshServer sshd = SshServer.setUpDefaultServer();
        sshd.setHost("localhost");
        sshd.setPort(2222);
        sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider(new File("host.ser")));
        sshd.setSubsystemFactories(Collections.singletonList(new SftpSubsystemFactory()));
        sshd.setPasswordAuthenticator((username, password, session) -> username.equals("test") && password.equals("password"));
        sshd.setPublickeyAuthenticator(new AuthorizedKeysAuthenticator(new File("<Location of authorized_keys file>")));
        sshd.start();
        log.info("SFTP server started");
    }
}

Similar to what @northshorefiend mentioned in his answer, in this case AuthorizedKeysAuthenticator takes the public key passed to the server and validates it against the authorized_keys file new AuthorizedKeysAuthenticator(new File("<Location of authorized_keys file>") . If the specified public key exists in the file, then it passes the authentication.

You can read more details about this here and here

Upvotes: 1

northshorefiend
northshorefiend

Reputation: 111

I think I found the answer in the source of org.apache.sshd.server.auth.UserAuthPublicKey#auth. This class does the actual auth with the key. I think what confused me is the name of the method - authenticate(). What really happens is as follows:

  • The server asks for the public key of the client

  • The public key is passed to PublickeyAuthenticator#authenticate

  • All you are supposed to do in authenticate() is check that this is a public key that you want to allow

  • If authenticate() returns true, then UserAuthPublicKey#auth will check that a message has been signed with the private key. If it has then authentication has been validated.

Upvotes: 8

Related Questions