如何使用Python生成SSH密钥对

Lee*_*Lee 33 python ssh ssh-keys m2crypto

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

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

该文件/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-----
Run Code Online (Sandbox Code Playgroud)

当我在找东西时:

ssh-rsa AAAABCASDDBM$%3WEAv/3%$F ..... OSDFKJSL43$%^DFg==
Run Code Online (Sandbox Code Playgroud)

Dav*_*ter 41

cryptography!pycrypto不再处于活跃开发状态,如果可能,您应该使用加密技术.从6月开始,也可以生成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
)
Run Code Online (Sandbox Code Playgroud)

注意:您至少需要版本1.4.0.

  • 注意事项:`cryptography> = 1.4.0`的版本要求并且缺少import语句:`来自cryptography.hazmat.backends import default_backend as crypto_default_backend` (4认同)

小智 34

万一有未来的旅行者希望这样做.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", 0600)
    content_file.write(key.exportKey('PEM'))
pubkey = key.publickey()
with open("/tmp/public.key", 'wb') as content_file:
    content_file.write(pubkey.exportKey('OpenSSH'))
Run Code Online (Sandbox Code Playgroud)

显然不要将你的私钥存放在/ tmp中......

  • 在`key.exportKey('PEM')`中,参数表示输出**格式**.有三个选项:'DER' - 二进制编码,'PEM' - 纹理编码,'OpenSSH' - 根据OpenSSH规范进行纹理编码. (5认同)
  • 为此使用加密技术而不是pycrypto; 请参阅其他答案http://stackoverflow.com/a/39126754#1301627 (2认同)
  • 在 Python3 中,八进制文字必须有一个“0o”前缀,所以:`chmod("/tmp/private.key", 0600)` 变成了 `chmod("/tmp/private.key", 0o600)` (2认同)

Jor*_*ona 6

编辑05/09/2012:

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

import os
from Crypto.PublicKey import RSA

key = RSA.generate(2048, os.urandom)
print key.exportKey('OpenSSH')
Run Code Online (Sandbox Code Playgroud)

这段代码适合我:

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())), )
Run Code Online (Sandbox Code Playgroud)


mde*_*ous 5

ssh 使用的密钥只是 base64 编码的,我不太了解 M2Crypto,但经过快速概述后,您似乎可以通过这种方式做您想做的事:

import os
from base64 import b64encode
from M2Crypto import RSA            

key = RSA.gen_key(1024, 65537)
raw_key = key.pub()[1]
b64key = b64encode(raw_key)

username = os.getlogin()
hostname = os.uname()[1]
keystring = 'ssh-rsa %s %s@%s' % (b64key, username, hostname)

with open(os.getenv('HOME')+'/.ssh/id_rsa.pub') as keyfile:
    keyfile.write(keystring)
Run Code Online (Sandbox Code Playgroud)

我没有用 SSH 测试生成的密钥,所以请告诉我它是否有效(我应该认为)


sar*_*mah 0

当它是一个对象时,你能从中获取 AAAA...Dfg== 字符串吗?如果是这样,您可以简单地自己打开一个文件并保存它,而不是使用内置的 save_pub_key 函数。