Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSCH addIdentity public key argument doesn't make a difference

Tags:

java

sftp

jsch

public class FTP {
  public static void main(String args[]){
    JSch jsch = new JSch();
    jsch.setKnownHosts("./known_hosts"); 

    Path privateKeyPath = Paths.get("./id_dsa");
    byte[] privateKey = Files.readAllBytes(privateKeyPath);

    Path publicKeyPath = Paths.get("./id_dsa.pub");
    byte[] publicKey = Files.readAllBytes(publicKeyPath);

    // Either of the lines below work... Why?
    // jsch.addIdentity("", privateKey, publicKey, null);
    // or 
    jsch.addIdentity("", privateKey, null, null);

    Session session = jsch.getSession("USER", "myHost.com", 22);

    session.connect();

  }
}

Setting publicKey to null, doesn't make a difference, I can connect either way. Why is that?

It looks like the publicKey isn't being used, so why pass it to addIdentity in the first place?

like image 358
Kam Avatar asked Jan 04 '23 18:01

Kam


1 Answers

It's an optimization for (some) encrypted private keys. You didn't notice any difference because you used unencrypted private keys.

If you give jsch an OpenSSL-format encrypted private key, and don't up-front provide the passphrase to decrypt it, but do provide the public key (which is never encrypted), and that keypair becomes the next choice for authentication, jsch probes the server using the publickey to determine if the server will possibly accept auth with this key. If so, jsch must prompt for the passphrase to decrypt the privatekey to actually perform authentication; if not, it skips the prompting and goes to the next possibility, if any. See the source for com.jcraft.jsch.UserAuthPublicKey.java.

The OpenSSH client ssh does almost the same thing. If you give it (as an option, in config or by default) an OpenSSL-format encrypted privatekey, and it finds a matching publickey, it probes first, and prompts for the passphrase to decrypt only if this key is usable. ssh does not allow specifying the passphrase in advance like Jsch.addIdentity, but it can use an ssh-agent process (or substitute) that accomplishes the same thing.

OpenSSH since 6.5 also supports 'new format' key files created with ssh-keygen -o which can have encrypted privatekey and unencrypted publickey in one file, avoiding handling publickey separately. Jsch does not (yet?) support this format, but it does support PuTTY's PPK format, which does the same thing, and thus for which you provide the single file as privatekey and no publickey.

like image 72
dave_thompson_085 Avatar answered Jan 25 '23 04:01

dave_thompson_085