为 SSHClient 设置允许的传输和 MAC 密码

Set allowed transport and MAC ciphers for SSHClient

我正在尝试使用 SSHJ 修改 SSH 客户端,以便它只允许某些密码。我在属性文件中有这样的属性:

sftp.transport.ciphers = aes256-gcm,aes256-ctr,aes256-etcera
sftp.mac.ciphers = hmac-sha3-512,...

使用Jsch限制使用的密码是这样的:

session.setConfig("cipher.s2c", sftpTransportCiphers);
session.setConfig("cipher.c2s", sftpTransportCiphers);

我一直在梳理 SSHJ 的文档,此时我已经 运行 兜了一圈,可能漏掉了什么,所以最好问一下。我没有看到一种干净的方法来获取逗号分隔的字符串并将其转换为密码列表,因为 SSHJ 会识别它。

一个简单的例子,SSHJ 的 SSHClient 配置类似于上面的 JSCH 版本,将不胜感激。

为了将来 reference/anyone 其他想要快速解决方案的人,这里有一个来自 DefaultConfig 的派生 class,正如 @Robert 所建议的。

    import net.schmizz.sshj.DefaultConfig;
    import net.schmizz.sshj.common.Factory;
    import net.schmizz.sshj.common.LoggerFactory;
    import net.schmizz.sshj.transport.cipher.*;
    import net.schmizz.sshj.transport.mac.MAC;
    import org.slf4j.Logger;

    import java.util.Arrays;
    import java.util.List;
    import java.util.Properties;
    import java.util.stream.Collectors;

    public class MyConfig extends DefaultConfig {
        private Logger logger;

        public MyConfig() {
            super();
            setLoggerFactory(LoggerFactory.DEFAULT);
        }

        @Override
        void setLoggerFactory(LoggerFactory loggerFactory) {
            super.setLoggerFactory(loggerFactory);
            logger = loggerFactory.getLogger(getClass());
        }

        public void setTransportCiphers(String input) {
            String[] ciphers = input.trim().split(",");
            List<String> factoryNames = Factory.Named.Util.getNames(getCipherFactories());

            List<Factory.Named<Cipher>> transportCiphers = Arrays.stream(ciphers)
                .filter(factoryNames::contains)
                .map(cipher -> Factory.Named.Util.get(getCipherFactories(), cipher))
                .collect(Collectors.toList());

            logger.info("Client-side cipher factories set to: {}", transportCiphers);

            setCipherFactories(transportCiphers);
        }

        public void setMacCiphers(String input) {
            String[] ciphers = input.trim().split(",");
            List<String> factoryNames = Factory.Named.Util.getNames(getMACFactories());

            List<Factory.Named<MAC>> macCiphers = Arrays.stream(ciphers)
                .filter(factoryNames::contains)
                .map(mac -> Factory.Named.Util.get(getMACFactories(), mac))
                .collect(Collectors.toList());

            logger.info(Client-side MAC factories set to: {}", Factory.Named.Util.getNames(macCiphers));

            setMACFactories(macCiphers);
        }
    }