非对称密码的私钥包含了公钥信息

一、Jsch的UserAuthPublicKey类

今日因为一个问题在看Jsch的UserAuthPublicKey源码时发现,如果我只传输私钥而不传输公钥,它会根据私钥计算出公钥,发送给服务侧。

非对称密码在实现时,会在私钥里包含完整的信息(包含生成公钥的信息),也就是说可以根据私钥计算出公钥。

二、解析

引自java - JSCH addIdentity公钥参数没有任何区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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();
}
}

根据回答可知,有两种场景:

1)当私钥未加密时

以下两种方法等效,当公钥为空时,会根据私钥计算出公钥,然后发送给服务器端验证。

1
2
3
4
// privateKey: 未加密私钥
// publicKey: 未加密公钥
jsch.addIdentity("", privateKey, publicKey, null);
jsch.addIdentity("", privateKey, null, null);

2)当私钥匙加密时

发送公钥给服务器验证,并仅在此密钥可用时客户端提示密码短语解密私钥获取未加密私钥。

1
2
3
// privateKeyEncrypt: 加密私钥
// publicKey: 未加密公钥
jsch.addIdentity("", privateKeyEncrypt, publicKey, null);

三、通过私钥生成私钥

1
$ ssh-keygen -y -f id_rsa > id_rsa.pub

# 参考

  1. can-i-get-a-public-key-from-an-rsa-private-key
  2. 知乎:RSA非对称可以通过私钥获取公钥吗?
  3. java - JSCH addIdentity公钥参数没有任何区别

评论