Apache mina sshd аутентифицирует подписи клиента

Я пытаюсь аутентифицировать подпись, которую клиенты генерируют из своего закрытого ключа и отправляют на сервер.

Единственный аутентификатор, который я смог найти в библиотеке, которая звучит уместно, была PublickeyAuthenticator. Пожалуйста, исправьте меня, если это неправильный класс, чтобы сделать это.

В настоящее время у меня есть:

this.sshServer.setPublickeyAuthenticator(new PublickeyAuthenticator() {
                @Override
                public boolean authenticate(String username, PublicKey key, ServerSession session) {
                    if (username.equals("client")) {
                         //if signature == valid??
                         return true;
                    }
                }
            });

Кто-нибудь знает, поддерживает ли mina проверку подписи, и если да, то как она может быть реализована?

Я понимаю, что мне сначала нужно назначить/добавить открытый ключ пользователя на сервер. Если клиент предоставил файл id_rsa.pub, как я могу добавить этот файл на сервер в качестве открытого ключа?

Ответ 1

Mina SSH имеет несколько реализаций PublickeyAuthenticator.
смотреть на org.apache.sshd.server.config.keys.AuthorizedKeysAuthenticator и org.apache.sshd.server.auth.pubkey.KeySetPublickeyAuthenticator.
Реализации PublickeyAuthenticator проверяют только то, что данный открытый ключ связан с пользователем.
Фактическая проверка подписи обрабатывается внутри MINA SSH после аутентификации.
AuthorizedKeysAuthenticator поддерживает только одного пользователя (он не проверяет имя пользователя), но вы можете, например, просто указать его в свой id_rsa.pub файл, и он должен работать.

this.sshServer.setPublickeyAuthenticator(
    new AuthorizedKeysAuthenticator(new File("id_rsa.pub"));

Вы можете написать свой собственный PublickeyAuthenticator, который проверяет ключи на карте таких пользователей:

public class UserKeySetPublickeyAuthenticator implements PublickeyAuthenticator {
    private final Map<String, Collection<? extends PublicKey>> userToKeySet;

    public UserKeySetPublickeyAuthenticator(Map<String, Collection<? extends PublicKey>> userToKeySet) {
        this.userToKeySet = userToKeySet;
    }

    @Override
    public boolean authenticate(String username, PublicKey key, ServerSession session) {
        return KeyUtils.findMatchingKey(key, userToKeySet.getOrDefault(username, Collections.emptyList())) != null;
    }

}

Вам нужно написать код, чтобы заполнить карту своими ключевыми данными. AuthorizedKeyEntry имеет методы утилиты для этого из файлов, входных потоков или строк.
Пример чтения от пользователя с именем разрешенных ключевых файлов:

Map<String, List<PublicKey>> userKeysMap = new HashMap<>();
List<String> users = Arrays.asList("Jim", "Sally", "Bob");
for(String user : users){
    List<PublicKey> usersKeys = new ArrayList<>();
    for(AuthorizedKeyEntry ake : AuthorizedKeyEntry.readAuthorizedKeys(new File(user + "_authorized_keys"))){
        PublicKey publicKey = ake.resolvePublicKey(PublicKeyEntryResolver.IGNORING);
        if(publicKey != null){
            usersKeys.add(publicKey);
        }
    }
    userKeysMap.put(user, usersKeys);
}