ssh-keygen 在 macOS Ventura 13.1 上的 python3.10 中使用 subprocess.run 和 os.system 输出空

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

我一直在尝试使用 python 和“子进程”库输出从 ssh-keygen (CLI) 生成的签名公钥。我也尝试过“os”库,得到了相同的结果。我真的很想了解为什么它没有执行我想要的操作:将“ssh-keygen -Lf {keyfile}”的输出显示到屏幕上,就像我期望的那样。

当我使用 CLI (darwin / macOS Ventura 13.1) 在同一个密钥文件上使用此命令时,我得到了预期的结果。当我在 Python3.10 中使用该命令时,我得到的返回码为“1”,并且没有重大错误来帮助我理解问题。请看下面:

预期结果:

shell-prompt$> ssh-keygen -Lf ~/.ssh/signed_key.pub
/Users/USER/.ssh/signed_kali-os.pub:
        Type: [email protected] user certificate
        Public key: RSA-CERT SHA256:REDACTED
        Signing CA: RSA SHA256:REDACTED (using rsa-sha2-256)
        Key ID: "[email protected]"
        Serial: REDACTED
        Valid: from 2023-01-24T20:56:07 to 2023-01-24T21:01:37
        Principals: 
                principal-user
        Critical Options: (none)
        Extensions: 
                permit-pty

基本 Python3.10 脚本的输出在打印返回代码时为“1”,在打印 stdout 和/或 stderr 时为空(无)。我已经尝试了所有我能想到的印刷方式。

这是我尝试过但没有成功的两个代码解决方案。当我用“ls -l”或“cat”等基本命令替换命令(ssh-keygen)时,我得到了预期的输出。我确信变量signedPath 按预期工作,因为它在未显示的代码的其他部分中工作,并且当我用硬编码路径替换该变量时,它仍然失败。

1)
if sys.platform == "linux" or sys.platform == "linux2" or sys.platform == "darwin":
        keyOut = subprocess.run(['ssh-keygen','-Lf',signedPath],capture_output=True)
        print(keyOut.stdout.decode())
2)
os.system('ssh-keygen -Lf {key}'.format(key=signedPath))

我在寻找什么?最终,我想使用此代码将签名公钥输出到屏幕,因为我喜欢使用 ssh-keygen 获得的输出格式,并且我在使用 Python 中的其他 SSH 密钥库时遇到了问题。如果有更好的解决方案,我很乐意获得一些帮助,但我真的决心尝试理解为什么这个特定的代码不起作用,所以我想要的不仅仅是一个答案单独的解决方案。非常感谢这里的任何帮助。

python python-3.x subprocess os.system ssh-keygen
1个回答
0
投票

考虑此代码,其中 (a) 生成用作签名证书的密钥,(b) 生成要签名的密钥,然后 (c) 使用 (a) 中的密钥对 (b) 中的密钥进行签名:

#!/usr/bin/python

import os
import subprocess

expected_files = [
    "ca_key",
    "ca_key.pub",
    "user_key",
    "user_key.pub",
    "user_key-cert.pub",
]

for name in expected_files:
    try:
        os.remove(name)
    except FileNotFoundError:
        pass

# I'm using `check_output` -- and ignoring the return value -- in order to
# supress the output from these commands. This is effectively a shortcut
# for `subprocess.run` with `capture_output=True` and `check=True`.
print("generating keys")
subprocess.check_output(["ssh-keygen", "-t", "rsa", "-f", "ca_key", "-N", ""])
subprocess.check_output(["ssh-keygen", "-t", "rsa", "-f", "user_key", "-N", ""])
subprocess.check_output(
    ["ssh-keygen", "-s", "ca_key", "-I", "user_key", "user_key.pub"]
)

# Verify that we created everything we expected to create.
for name in expected_files:
    assert os.path.isfile(name)

# Here's the code from your question.
signedPath = "user_key-cert.pub"
keyOut = subprocess.run(["ssh-keygen", "-Lf", signedPath], capture_output=True)

print("keyOut:", keyOut.stdout.decode())

上面的代码是一个独立的示例:它创建了所有必要的文件来运行您在问题中询问的代码;有人可以暗示复制该示例,将其粘贴到文件中,然后运行它。

在我的系统(

sys.platform
==
linux
)上,运行此示例会产生:

generating keys
Signed user key user_key-cert.pub: id "user_key" serial 0 valid forever
keyOut: user_key-cert.pub:
        Type: [email protected] user certificate
        Public key: RSA-CERT SHA256:Bca+gRvhx3twR0vFhIU3gr+TKIfFq2I1+lraJ6Z2QAI
        Signing CA: RSA SHA256:muz+6U5h9ZGyslm50m1F0VNG8VrseuQRzYwdUm2iGoo (using rsa-sha2-512)
        Key ID: "user_key"
        Serial: 0
        Valid: forever
        Principals: (none)
        Critical Options: (none)
        Extensions:
                permit-X11-forwarding
                permit-agent-forwarding
                permit-port-forwarding
                permit-pty
                permit-user-rc

如果您在 Linux 系统上运行代码并且看到不同的行为,我相信通过有关您的环境的一些其他详细信息,我们可以弄清楚发生了什么。

© www.soinside.com 2019 - 2024. All rights reserved.