首页 > 解决方案 > 使用 pysftp 连接到 SFTP 服务器时出现“SSHException:遇到 EC 密钥,预期的 DSA 密钥”

问题描述

我一直在尝试使用以下参数通过 Python pysftp 创建一个 SFTP 连接

import pysftp
srv = pysftp.Connection(host="some.hostname.com", username="username",
private_key="path/key.ppk",port=22,private_key_pass="key")

srv.chdir('/upload/')
srv.put('path/test.csv')
print('file Uploaded')
srv.close()

不幸的是,这给出了错误

SSHException:不是有效的 DSA 私钥文件

完整追溯:

SSHException: not a valid DSA private key file 
---------------------------------------------------------------------------
SSHException                              Traceback (most recent call last)
~\.conda\envs\env_scrapy\lib\site-packages\pysftp.py in __init__(self, host, username, private_key, password, port, private_key_pass, ciphers, log)
    178                     prv_key = rsakey.from_private_key_file(private_key_file,
--> 179                                                            private_key_pass)
    180                 except paramiko.SSHException:   #if it fails, try dss

~\.conda\envs\env_scrapy\lib\site-packages\paramiko\pkey.py in from_private_key_file(cls, filename, password)
    234         """
--> 235         key = cls(filename=filename, password=password)
    236         return key

~\.conda\envs\env_scrapy\lib\site-packages\paramiko\rsakey.py in __init__(self, msg, data, filename, password, key, file_obj)
     54         if filename is not None:
---> 55             self._from_private_key_file(filename, password)
     56             return

~\.conda\envs\env_scrapy\lib\site-packages\paramiko\rsakey.py in _from_private_key_file(self, filename, password)
    174     def _from_private_key_file(self, filename, password):
--> 175         data = self._read_private_key_file("RSA", filename, password)
    176         self._decode_key(data)

~\.conda\envs\env_scrapy\lib\site-packages\paramiko\pkey.py in _read_private_key_file(self, tag, filename, password)
    307         with open(filename, "r") as f:
--> 308             data = self._read_private_key(tag, f, password)
    309         return data

~\.conda\envs\env_scrapy\lib\site-packages\paramiko\pkey.py in _read_private_key(self, tag, f, password)
    323         if start >= len(lines) or keytype is None:
--> 324             raise SSHException("not a valid {} private key file".format(tag))
    325 

SSHException: not a valid RSA private key file

我收到了该key.ppk文件,我尝试通过 PuTTYgen 将其转换为密钥文件,并将该文件用作上述代码中的密钥文件。我收到另一个 SSHException

SSHException:遇到 EC 密钥,预期 DSA 密钥

SSHException: encountered EC key, expected DSA key
---------------------------------------------------------------------------
SSHException                              Traceback (most recent call last)
~\.conda\envs\env_scrapy\lib\site-packages\pysftp.py in __init__(self, host, username, private_key, password, port, private_key_pass, ciphers, log)
    178                     prv_key = rsakey.from_private_key_file(private_key_file,
--> 179                                                            private_key_pass)
    180                 except paramiko.SSHException:   #if it fails, try dss

~\.conda\envs\env_scrapy\lib\site-packages\paramiko\pkey.py in from_private_key_file(cls, filename, password)
    234         """
--> 235         key = cls(filename=filename, password=password)
    236         return key

~\.conda\envs\env_scrapy\lib\site-packages\paramiko\rsakey.py in __init__(self, msg, data, filename, password, key, file_obj)
     54         if filename is not None:
---> 55             self._from_private_key_file(filename, password)
     56             return

~\.conda\envs\env_scrapy\lib\site-packages\paramiko\rsakey.py in _from_private_key_file(self, filename, password)
    174     def _from_private_key_file(self, filename, password):
--> 175         data = self._read_private_key_file("RSA", filename, password)
    176         self._decode_key(data)

~\.conda\envs\env_scrapy\lib\site-packages\paramiko\pkey.py in _read_private_key_file(self, tag, filename, password)
    307         with open(filename, "r") as f:
--> 308             data = self._read_private_key(tag, f, password)
    309         return data

~\.conda\envs\env_scrapy\lib\site-packages\paramiko\pkey.py in _read_private_key(self, tag, f, password)
    340             raise SSHException(
--> 341                 "encountered {} key, expected {} key".format(keytype, tag)
    342             )

SSHException: encountered EC key, expected RSA key

During handling of the above exception, another exception occurred:


SSHException                              Traceback (most recent call last)
<ipython-input-31-ef0970250b08> in <module>
      1 srv = pysftp.Connection(host="sftp.doubleaste.com", username="aimleap",
----> 2 private_key="path/finalkey",private_key_pass="keypass")
      3 srv.chdir('/upload/')
      4 # srv.put('path/test.csv')
      5 print('file Uploaded')
~\.conda\envs\env_scrapy\lib\site-packages\pysftp.py in __init__(self, host, username, private_key, password, port, private_key_pass, ciphers, log)
    181                     dsskey = paramiko.DSSKey
    182                     prv_key = dsskey.from_private_key_file(private_key_file,
--> 183                                                            private_key_pass)
    184             else:
    185                 # use the paramiko agent key

~\.conda\envs\env_scrapy\lib\site-packages\paramiko\pkey.py in from_private_key_file(cls, filename, password)
    233         :raises: `.SSHException` -- if the key file is invalid
    234         """
--> 235         key = cls(filename=filename, password=password)
    236         return key
    237 

~\.conda\envs\env_scrapy\lib\site-packages\paramiko\dsskey.py in __init__(self, msg, data, filename, password, vals, file_obj)
     63             return
     64         if filename is not None:
---> 65             self._from_private_key_file(filename, password)
     66             return
     67         if (msg is None) and (data is not None):

~\.conda\envs\env_scrapy\lib\site-packages\paramiko\dsskey.py in _from_private_key_file(self, filename, password)
    222 
    223     def _from_private_key_file(self, filename, password):
--> 224         data = self._read_private_key_file("DSA", filename, password)
    225         self._decode_key(data)
    226 

~\.conda\envs\env_scrapy\lib\site-packages\paramiko\pkey.py in _read_private_key_file(self, tag, filename, password)
    306         """
    307         with open(filename, "r") as f:
--> 308             data = self._read_private_key(tag, f, password)
    309         return data
    310 

~\.conda\envs\env_scrapy\lib\site-packages\paramiko\pkey.py in _read_private_key(self, tag, f, password)
    339         else:
    340             raise SSHException(
--> 341                 "encountered {} key, expected {} key".format(keytype, tag)
    342             )
    343 

SSHException: encountered EC key, expected DSA key

尝试ECDSAKey明确使用类:

private_key1 = ECDSAKey.from_private_key_file("path/finalkey", password="pass")
srv = pysftp.Connection(host="host", username="name", private_key=private_key1)
srv.chdir('/upload/')
srv.put('path/test.csv')
print('file Uploaded')
srv.close()

我得到:

TypeError:预期的 str、字节或 os.PathLike 对象,而不是 ECDSAKey

TypeError: expected str, bytes or os.PathLike object, not ECDSAKey
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-72-880edc39ff10> in <module>
      1 srv = pysftp.Connection(host="hostname", username="user",
----> 2 private_key=private_key1,private_key_pass="pass")
      3 srv.chdir('/upload/')
      4 # srv.put('test.csv')
      5 print('file Uploaded')

~\.conda\envs\env_scrapy\lib\site-packages\pysftp\__init__.py in __init__(self, host, username, private_key, password, port, private_key_pass, ciphers, log, cnopts, default_path)

~\.conda\envs\env_scrapy\lib\site-packages\pysftp\__init__.py in _set_authentication(self, password, private_key, private_key_pass)

~\.conda\envs\env_scrapy\lib\ntpath.py in expanduser(path)
    289 
    290     If user or $HOME is unknown, do nothing."""
--> 291     path = os.fspath(path)
    292     if isinstance(path, bytes):
    293         tilde = b'~'

TypeError: expected str, bytes or os.PathLike object, not ECDSAKey

标签: pythonpython-3.xsshputtypysftp

解决方案


从 0.2.9 版开始,pysftp 仅接受 RSA 和 DSA 密钥。

如果你想/需要使用 ECDSA 密钥,你必须直接使用 Paramiko。pysftp 只是 Paramiko 周围的一个薄(和错误)包装器。

请注意,无论如何您都需要将 .ppk 密钥转换为 OpenSSH 格式。

相关问题:


推荐阅读