我可以在不知道 paramiko 类型的情况下读取 SSH 私钥吗?

问题描述 投票:0回答:1

我正在通过 SSH 密钥使用

paramiko.SSHClient
向远程服务器进行身份验证。为此,我有几个针对不同服务器的配置以及 SSH 密钥的路径。碰巧其中一些是 Ed25519,一些是 RSA。仅使用密码连接不是可接受的选择。

一开始我想用下面的代码连接:

keyfilename = build_configuration['sshPrivateKeypath']
keyfilename = os.path.expandvars(keyfilename)
key = paramiko.Ed25519Key.from_private_key_file(keyfilename)

ssh.connect(ssh_host, port=port, username=ssh_user, pkey=key)

但事实证明,有些密钥是 RSA(不是 Ed25519)。

有没有办法在不使用具体实现的情况下读取任何类型的 SSH 密钥?或者也许有某种方法可以确定类型? 或者唯一的方法是将所有键更改为已知类型?

无法从文档

中计算出来

在测试真实配置之前,我尝试从 Jupyter 读取本地 PC 上的 SSH 密钥。 当读错这样的类型时:

keyfilename = "%USERPROFILE%/.ssh/id_rsa"
keyfilename = os.path.expandvars(keyfilename)
privateKey = paramiko.Ed25519Key.from_private_key_file(keyfilename)

它抛出:

---------------------------------------------------------------------------
SSHException                              Traceback (most recent call last)
Cell In[2], line 6
      4 keyfilename = "%USERPROFILE%/.ssh/id_rsa"
      5 keyfilename = os.path.expandvars(keyfilename)
----> 6 privateKey = paramiko.Ed25519Key.from_private_key_file(keyfilename)
      7 display(key)
      8 display(privateKey)

File ~\AppData\Local\Programs\Python\Python311\Lib\site-packages\paramiko\pkey.py:421, in PKey.from_private_key_file(cls, filename, password)
    400 @classmethod
    401 def from_private_key_file(cls, filename, password=None):
    402     """
    403     Create a key object by reading a private key file.  If the private
    404     key is encrypted and ``password`` is not ``None``, the given password
   (...)
    419     :raises: `.SSHException` -- if the key file is invalid
    420     """
--> 421     key = cls(filename=filename, password=password)
    422     return key

File ~\AppData\Local\Programs\Python\Python311\Lib\site-packages\paramiko\ed25519key.py:65, in Ed25519Key.__init__(self, msg, data, filename, password, file_obj)
     62     pkformat, data = self._read_private_key("OPENSSH", file_obj)
     64 if filename or file_obj:
---> 65     signing_key = self._parse_signing_key_data(data, password)
     67 if signing_key is None and verifying_key is None:
     68     raise ValueError("need a key")

File ~\AppData\Local\Programs\Python\Python311\Lib\site-packages\paramiko\ed25519key.py:114, in Ed25519Key._parse_signing_key_data(self, data, password)
    112     pubkey = Message(message.get_binary())
    113     if pubkey.get_text() != self.name:
--> 114         raise SSHException("Invalid key")
    115     public_keys.append(pubkey.get_binary())
    117 private_ciphertext = message.get_binary()

SSHException: Invalid key

所以我希望当我使用真实配置尝试时它会抛出同样的结果。

python ssh paramiko ssh-keys
1个回答
0
投票

最简单的方法是使用

key_filename
SSHClient.connect
参数代替
pkey


如果您出于某种原因想要使用

pkey
,则在处理
SSHClient
时,您必须在内部复制
key_filename
的功能。大致是这样的(未经测试):

for pkey_class in (RSAKey, DSSKey, ECDSAKey, Ed25519Key):
    try:
        key = pkey_class.from_private_key_file(key_filename)
        break
    except SSHException as e:
        pass
© www.soinside.com 2019 - 2024. All rights reserved.