sshj icon indicating copy to clipboard operation
sshj copied to clipboard

Problem using PuTTYKeyFile

Open dhubbard-ic opened this issue 7 years ago • 1 comments

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.

dhubbard-ic avatar Oct 26 '18 12:10 dhubbard-ic

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

ljluestc avatar Feb 02 '25 06:02 ljluestc