【问题标题】:apache mina sshd authenticate client signaturesapache mina sshd 验证客户端签名
【发布时间】:2019-07-22 20:08:41
【问题描述】:

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

我能在库中找到的唯一一个听起来合适的身份验证器是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 文件,我该如何将此文件作为公钥添加到服务器?

【问题讨论】:

    标签: java sshd java-security apache-mina


    【解决方案1】:

    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);
    }
    

    【讨论】:

    • 有没有办法注册多个公钥并为每个用户验证它们?
    • 我已经用一个示例更新了答案,说明如何为多个用户实现它。
    猜你喜欢
    • 2023-02-02
    • 2016-04-11
    • 1970-01-01
    • 2017-04-07
    • 1970-01-01
    • 1970-01-01
    • 2015-09-02
    • 2015-07-01
    • 1970-01-01
    相关资源
    最近更新 更多