我一直在尝试使用 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 密钥库时遇到了问题。如果有更好的解决方案,我很乐意获得一些帮助,但我真的决心尝试理解为什么这个特定的代码不起作用,所以我想要的不仅仅是一个答案单独的解决方案。非常感谢这里的任何帮助。
考虑此代码,其中 (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 系统上运行代码并且看到不同的行为,我相信通过有关您的环境的一些其他详细信息,我们可以弄清楚发生了什么。