SSH IDキーペアを生成するスクリプトを記述しようとしています。
_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==
_
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
)
注:少なくともバージョン1.4.0
が必要です。
これを実行しようとする将来の旅行者がいる場合に備えて。 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'))
キーはバイナリモードで書き込む必要があるため、ファイルは「wb」で開きます。あなたの秘密鍵を/ tmpに保存しないでください...
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())), )
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)
生成されたキーをSSHでテストしなかったので、それが機能するかどうかを知らせてください(私はそう思うはずです)
Key.pub()の内容へのssh-keygen出力のbase64デコードバージョンは、キーファイルの形式です。
b64encode('\x00\x00\x00\x07ssh-rsa%s%s' % (key.pub()[0], key.pub()[1]))
subprocess
を使用してssh-keygen
を呼び出すのはどうですか?
from subprocess import Popen, PIPE
import shlex
def get_pub_key(path):
args = shlex.split('ssh-keygen -y -f')
args.append(path)
p = Popen(args, stdout=PIPE)
stdout = p.communicate()[0]
if p.returncode != 0:
raise Exception("Error handling would be Nice, eh?")
return stdout.strip()
print get_pub_key('/tmp/my.key')
上記の小さなプログラムは、次のような出力を生成します。
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA ... 9Jbn6D74JOKpaOU050ltyNRw ==
以下は、PyCryptoを活用したTwisted Conchライブラリの使用例です。 APIドキュメントは http://twistedmatrix.com/documents/current/api/twisted.conch.ssh.keys.html にあります。
from twisted.conch.ssh import keys
# one-time use key
k="""-----BEGIN RSA PRIVATE KEY-----
PRIVATE KEY STUFF
-----END RSA PRIVATE KEY-----"""
# create pycrypto RSA object
rsa = keys.RSA.importKey(k)
# create `twisted.conch.ssh.keys.Key` instance which has some Nice helpers
key = keys.Key(rsa)
# pull the public part of the key and export an openssh version
ssh_public = key.public().toString("openssh")
print ssh_public
必要に応じて、ssh-keygen
自体を使用することもできます。これを拡張してファイルを作成し、open
を使用して後でコンテンツを読み取ることもできますが、ここでは既存のキーから.pubキーを作成することに焦点を当てています。
from subprocess import Popen, PIPE
import os
home = f'{os.path.expanduser("~")}'
cert_pos = f'{home}/.ssh/my_key'
your_key_pw = ''
cmd = ['ssh-keygen', '-y', '-f', cert_pos]
if your_key_pw:
cmd.append('-P')
cmd.append(your_key_pw)
p = Popen(cmd, stdout=PIPE)
p.wait()
res, err = p.communicate()
cert_content = res.decode('utf-8')
オブジェクトである間、AAAA ... Dfg ==文字列を取得できますか?その場合は、組み込みのsave_pub_key関数を使用する代わりに、自分でファイルを開いて保存するだけです。
想像してみてください...しかし、あなたはこのようなことを試しましたか?:
print "ssh-rsa " + "".join([ l.strip() for l in open('/tmp/my.key.pub') if not l.startswith('-----')])
documentation で説明されているようにpycryptodome
を使用できます:
from Crypto.PublicKey import RSA
key = RSA.generate(2048)
private_key = key.export_key()
file_out = open("private.pem", "wb")
file_out.write(private_key)
public_key = key.publickey().export_key()
file_out = open("receiver.pem", "wb")
file_out.write(public_key)
Pythonに標準で付属しているそのようなライブラリについては知りません。
サードパーティのライブラリを調べたい場合は、 paramiko ライブラリが便利です(また、 PyPIから入手できます) )。 SSHプロトコルを実装し、既存のキーを処理するための機能を備えていますが、キーを生成しません。
キーの生成はそのライブラリへの便利な追加かもしれません( 開発者と協力して それをParamikoライブラリに組み込むことができます)。ゼロからそれを行う。