Problem using PuTTYKeyFile
Hi
I recently noticed the support for PuTTY Key File handling in SSHJ and am now using it.
However I have a further requirement to look at Putty Key file handling outside of SSHJ e.g. extract public key.
For this I have been looking at using the PuTTYKeyFile class directly, but I hit a few problems.
So is PuTTYKeyFile intended for API usage? I appreciate this is possibly engineering to be used under the covers within SSHJ.
If so then can I make a few observations that would improve it?
My main issue is when check a file (.ppk) to determine if it is encrypted.
I see that init() and isEncrypted() methods are public so should I be able to do this?
PuTTYKeyFile pkf = new PuTTYKeyFile();
pkf.init(new File("C:/myEncryptedPuttyFile.ppk"));
System.out.println("File is encrypted["+pkf.isEncrypted()+"]");
However with this I always get false.
The reason appears to be that isEncrypted() (which is public) inspects "headers" map, but used this way this map is empty. Digging a bit deeper I can see that "headers" is populated in "parseKeyPair()", but this is protected and therefore can't be directly called.
Now, as I say, it's possible that you never intended this class to be used externally from SSHJ, so should isEncrytped() should be "protected" scope rather than "public"?
But I think with a few tweaks this could be a very useful utility - if you agree then I could possibly take a deeper look and provide a pull request.
For my requirement I need to check the file is encrypted, before prompting user then supplying calling "init(File location, PasswordFinder pwdf)" to specify the password later.
import net.schmizz.sshj.common.KeyType;
import net.schmizz.sshj.common.SecurityUtils;
import net.schmizz.sshj.userauth.keyprovider.PKCS8KeyFile;
import net.schmizz.sshj.userauth.password.PasswordFinder;
import net.schmizz.sshj.userauth.password.Resource;
import java.io.File;
import java.io.IOException;
import java.util.Map;
public class PuTTYKeyFile extends PKCS8KeyFile {
private Map<String, String> headers;
@Override
public void init(File location) throws IOException {
super.init(location);
parseHeaders();
}
@Override
public void init(File location, PasswordFinder pwdf) throws IOException {
super.init(location, pwdf);
parseHeaders();
}
private void parseHeaders() throws IOException {
// Parse the headers from the file
headers = SecurityUtils.getPuTTYKeyFileHeaders(resource);
}
public boolean isEncrypted() {
return headers != null && "aes256-cbc".equals(headers.get("Encryption"));
}
@Override
public KeyType getType() {
return KeyType.fromString(headers.get("Key-Type"));
}
}