使用python将.ppk文件转换为带有tempfile的.pem

a11xaf1n  于 2023-06-25  发布在  Python
关注(0)|答案(1)|浏览(102)

我想写一个快速的API端点的功能,获得.ppk文件,并将其转换为.pem连接到SFTP下载一些文件使用Python,而不存储在本地系统中。
如果我使用直接.pem文件,它有助于连接到SFTP并下载文件,但需要知道如何使用.ppk文件。
已尝试使用子进程运行命令,并将扩展名为.pem的数据存储在临时文件中,但执行子进程后临时文件仍为空。Popen。
ppk文件需要密码。
运行下面的命令转换为.pem文件,通过询问输入密码来加载密钥:

puttygen "/home/ubuntu/Music/SFTP_Private_Key.ppk" -O private-openssh -o "/home/ubuntu/Music/SFTP_Private_Key_convert.pem"

我喜欢在Python中使用函数。任何东西,我错过了这里!!!...提前感谢。下面是我的代码。

import paramiko
import tempfile
import subprocess
import shlex

use_host = 'testfile.random.com'
use_port = 22
use_username = 'tester123'
use_password = '1234567890'
use_ppk_path = '/home/ubuntu-test/Music/SFTP_Private_Key.ppk'

use_temp_pem_file = tempfile.NamedTemporaryFile(mode='w', delete=False, suffix=".pem")
use_pem_path = use_temp_pem_file.name
use_cmd = f'puttygen "{use_ppk_path}" -O private-openssh -o "{use_pem_path}" --old-passphrase "{use_password}"'

use_process = subprocess.Popen(
    use_cmd,
    shell=True,
    stdin=subprocess.PIPE
)
use_process.communicate(input=use_password.encode())
if use_process.returncode != 0:
    print(f"Error executing command: {use_cmd}")
    print(f"Command returned non-zero exit status: {use_process.returncode}")
    print(f"Error output-stderr:\n{use_process.stderr}")
    print(f"Error output-stdout:\n{use_process.stdout}")

with open(use_pem_path, 'r') as use_f:
    use_f.seek(0)
    use_file_contents = use_f.read()
    print('file_contents', use_file_contents)

use_ssh = paramiko.SSHClient()

use_ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
private_key = paramiko.RSAKey.from_private_key_file(filename=use_pem_path)
use_ssh.connect(use_host, port=use_port, username=use_username, password=use_password, key_filename=private_key)
use_sftp = use_ssh.open_sftp()

已尝试类似命令

> f'puttygen "{use_ppk_path}" -O private-openssh -o "{use_pem_path}" --old-passphrase "{use_password}"'
> f'puttygen "{use_ppk_path}" -O private-openssh -o "{use_pem_path}" -P "{use_password}"'
> f'puttygen "{use_ppk_path}" -O private-openssh -o "{use_pem_path}"' #last command ask password in separate window while code execution, which can't do in live session.

错误:
use_f.read()始终为空。
private_key = paramiko.RSAKey.from_private_key_file(filename=use_pem_path)----> paramiko.ssh_exception.SSHException:不是有效的RSA私钥文件
也检查了tempfile_path,文件中的内容仍为空。

use_temp_pem_file = tempfile.NamedTemporaryFile(mode='w', delete=False, suffix=".pem")      
use_pem_path = use_temp_pem_file.name      
use_cmd = f'puttygen "{use_ppk_path}" -O private-openssh -o "{use_pem_path}"'     
    try:         
        with open(use_temp_pem_file, 'r') as use_f:             
            for line in use_f:                 
                print(line)             
            use_f.seek(0)             
            use_file_contents = use_f.read()     
    except:         
         use_file_contents = ""     
    print('file_contents', use_file_contents)

尝试:

# with open(use_temp_pem_file, 'r') as use_f:
use_temp_pem_file.seek(0)
use_file_contents = use_temp_pem_file.read()
print('file_contents', use_file_contents)
# Still its empty values

错误消息:TypeError:应为str、bytes或os.PathLike对象,而不是_TemporaryFileWrapper
我发现了这个代码片段http://www.example-code.com/python/ssh_ppk_to_pem.asp,但我不确定使用-chilkat-库是否是个好主意。它的自由与否

wh6knrhe

wh6knrhe1#

找到了答案使用pexpect代替subprocessdoc-here

child = pexpect.spawn(f'puttygen "{use_ppk_path}" -O private-openssh -o "{use_pem_path}"')
        child.expect('Enter passphrase to load key:')
        child.sendline(use_password)

        use_temp_pem_file.seek(0)
        use_file_contents = use_temp_pem_file.read()

相关问题