I'm trying to modify an SSH client using SSHJ so that it only allows certain ciphers. I have properties in a properties file something like this:
sftp.transport.ciphers = aes256-gcm,aes256-ctr,aes256-etcera
sftp.mac.ciphers = hmac-sha3-512,...
Using Jsch limiting ciphers used would be like so:
session.setConfig("cipher.s2c", sftpTransportCiphers);
session.setConfig("cipher.c2s", sftpTransportCiphers);
I've been combing through the docs for SSHJ and at this point I've run around in circles a bit and probably missed something, so best to just ask. I'm not seeing a clean way to take a comma-delimited string and turn it into a list of ciphers as SSHJ would recognize it.
A simple example with SSHJ's SSHClient configured similarly to the JSCH version above would be greatly appreciated.
For future reference/anyone else who wants a quick solution, here's a derived class from DefaultConfig, as suggested by @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);
}
}