JSCH addIdentity public key argument doesn't make a difference

▼魔方 西西 提交于 2020-05-13 07:55:10

问题


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?


回答1:


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.




回答2:


The private key contains the information needed to construct the public key. If jsch needs the public key, it can get it from the private key.

As an example, you can use ssh-keygen to extract the public key from a private key file:

$ ssh-keygen -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key (/Users/foo/.ssh/id_dsa): key
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
...
$ ls -l
total 16
-rw-------  1 foo  bar  668 Jan 12 16:28 key
-rw-r--r--  1 foo  bar  613 Jan 12 16:28 key.pub
$ cat key.pub
ssh-dss AAAAB3NzaC1kc3MAAACBANzp8qnI3e+iO/5KkK...
$ rm key.pub
$ ssh-keygen -y -f key
ssh-dss AAAAB3NzaC1kc3MAAACBANzp8qnI3e+iO/5KkK...


来源:https://stackoverflow.com/questions/41622662/jsch-addidentity-public-key-argument-doesnt-make-a-difference

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!