Search code examples
pythonpython-3.xsftppempysftp

pysftp "paramiko.ssh_exception.AuthenticationException: Authentication failed."


I have access to an SFTP server using username and a ppk file. All information I have are

  • host
  • username
  • ppk priveate key file
  • the password for decrypting the ppk file

There is no server password. The password is for ppk file decryption only.

If I user Filezilla, it connects to the server fine.

Now, I would like to use python to connect to the same server. It seems pysftp which is an wrapper on paramiko is only supporting pem format and not ppk keys. I used putty gen for this conversion. It seem that RSA is not acceptable so I used DSA for this conversion. Provided the ppk file and its password and generated a pem private key file.

Now, following this code:

import pysftp
cnopts = pysftp.CnOpts()
cnopts.hostkeys = None
srv = pysftp.Connection(host=sftp_host, username=sftp_user, private_key='auth.pem', cnopts=cnopts)

After a few seconds, I receive this error:

paramiko.ssh_exception.AuthenticationException: Authentication failed.

What would you advise?

Notes:

  • I have tried many stackoverflow answers and did not have any success. Therefore, please avoid linking this question to another random question with similar title. Instead please suggest a solution and wait for my feedback on why it does not work me.

  • I use a private key file. Please avoid referring me to the questions that use username/password for SFTP.

  • Please avoid referring me to the questions for SSH because I do not know how to put it in SFTP context.

  • This is about pysftp please do not suggest the options of paramiko. They do not work on a pysftp function.


Solution

  • I could eventually fix the problem. This was by lots of efforts plus the hints from user @martin-prikryl .

    I share my solution code for others who will face with this problem in future.

    The point is that there is a bug in the python library and you need to get around it by disabled_algorithms . I could not find such an option in pysftp so I migrated the code entirely to pure paramiko.

    import paramiko
    import io
    
    with open('the_private_key.pem', 'r') as fh:
        keydata = fh.read()
    keyfile = io.StringIO(keydata)
    mykey = paramiko.RSAKey.from_private_key(keyfile)
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(sftp_host, username=sftp_user, pkey=mykey, look_for_keys=False, disabled_algorithms=dict(pubkeys=["rsa-sha2-512", "rsa-sha2-256"]))
    sftp = ssh.open_sftp()
    file_list = sftp.listdir()
    

    .