Apache Mina SSHD验证客户端签名

14

我正试图验证客户端使用其私钥生成并发送到服务器的签名。

我在库中找到的唯一适合的身份验证器是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个回答

7

Mina SSH有几个PublickeyAuthenticator的实现。
请看org.apache.sshd.server.config.keys.AuthorizedKeysAuthenticatororg.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);
}

有没有一种方法可以注册多个公钥并按用户验证它们? - Hooli
我已经更新了答案,并提供了一个示例,说明如何为多个用户实现它。 - Magnus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接