如何用Python生成SSH密钥对

56 投票
11 回答
103005 浏览
提问于 2025-04-15 20:33

我正在尝试写一个脚本,来为我生成SSH身份密钥对。

from M2Crypto import RSA
key = RSA.gen_key(1024, 65337)
key.save_key("/tmp/my.key", cipher=None)

现在文件/tmp/my.key看起来很好。

通过运行ssh-keygen -y -f /tmp/my.key > /tmp/my.key.pub,我可以提取出公钥。

我的问题是,如何从Python中提取公钥?使用key.save_pub_key("/tmp/my.key.pub")保存的内容像这样:

-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADASDASDASDASDBarYRsmMazM1hd7a+u3QeMP
...
FZQ7Ic+BmmeWHvvVP4Yjyu1t6vAut7mKkaDeKbT3yiGVUgAEUaWMXqECAwEAAQ==
-----END PUBLIC KEY-----

但我想要的是这样的内容:

ssh-rsa AAAABCASDDBM$%3WEAv/3%$F ..... OSDFKJSL43$%^DFg==

11 个回答

5

编辑于2012年5月9日:

我刚刚意识到pycrypto已经有这个功能了:

import os
from Crypto.PublicKey import RSA

key = RSA.generate(2048, os.urandom)
print key.exportKey('OpenSSH')

这段代码对我来说是有效的:

import os
from Crypto.PublicKey import RSA

key = RSA.generate(2048, os.urandom)

# Create public key.                                                                                                                                               
ssh_rsa = '00000007' + base64.b16encode('ssh-rsa')

# Exponent.                                                                                                                                                        
exponent = '%x' % (key.e, )
if len(exponent) % 2:
    exponent = '0' + exponent

ssh_rsa += '%08x' % (len(exponent) / 2, )
ssh_rsa += exponent

modulus = '%x' % (key.n, )
if len(modulus) % 2:
    modulus = '0' + modulus

if modulus[0] in '89abcdef':
    modulus = '00' + modulus

ssh_rsa += '%08x' % (len(modulus) / 2, )
ssh_rsa += modulus

public_key = 'ssh-rsa %s' % (
    base64.b64encode(base64.b16decode(ssh_rsa.upper())), )
45

如果将来有小伙伴想要做这个,RSA模块现在支持以OpenSSH格式输出公钥(可能在之前的帖子中不支持)。所以我觉得你可以用下面的方式来完成你的需求:

from os import chmod
from Crypto.PublicKey import RSA

key = RSA.generate(2048)
with open("/tmp/private.key", 'wb') as content_file:
    chmod("/tmp/private.key", 0o600) #use an 0o prefix for octal integers
    content_file.write(key.exportKey('PEM'))
pubkey = key.publickey()
with open("/tmp/public.key", 'wb') as content_file:
    content_file.write(pubkey.exportKey('OpenSSH'))

文件是用'wb'模式打开的,因为密钥必须以二进制模式写入。显然,别把你的私钥存放在/tmp目录下……

94

使用 cryptographypycrypto 现在已经不再更新了,如果可以的话,最好用 cryptography。从六月开始,它也可以生成 SSH 公钥了:

from cryptography.hazmat.primitives import serialization as crypto_serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.backends import default_backend as crypto_default_backend

key = rsa.generate_private_key(
    backend=crypto_default_backend(),
    public_exponent=65537,
    key_size=2048
)

private_key = key.private_bytes(
    crypto_serialization.Encoding.PEM,
    crypto_serialization.PrivateFormat.PKCS8,
    crypto_serialization.NoEncryption()
)

public_key = key.public_key().public_bytes(
    crypto_serialization.Encoding.OpenSSH,
    crypto_serialization.PublicFormat.OpenSSH
)

注意:你需要至少版本 1.4.0

注意:如果你的 SSH 客户端不支持这种私钥格式,可以 PKCS8 替换为 TraditionalOpenSSL

撰写回答