7

Using PyCrypto I was able to generate the public and private PEM serialization for a RSA key, but in PyCrypto the DSA class has no exportKey() method.

Trying PyOpenSSL I was able to generate the private PEM serialization for RSA and DSA keys, bu there is no crypto.dump_publickey method in PyOpenSSL.

I am looking for suggestion of how to generate the PEM serialization for RSA and DSA keys.

Many thanks!

PS: meanwhile I have changed the PyOpenSSL code to also export an dump_privatekey method for crypto API. PyOpenSSL bug and patch can be found at: https://bugs.launchpad.net/pyopenssl/+bug/780089


I was already using Twisted.conch so I solved this problem by manually generating a DSA/RSA key using PyCrypto and then initializing a twisted.conch.ssh.key.Key using this key. The Key class from Conch provides a toString method for string serialization.

Adi Roiban
  • 1,293
  • 2
  • 13
  • 28

1 Answers1

3

It is not clear what you are doing this for, but if all you want is an openssl-compatible DSA private key, you should just follow the openssl dsa(1) manual page:

The DER option with a private key uses an ASN1 DER encoded form of an ASN .1 SEQUENCE consisting of the values of version (currently zero), p, q, g, the public and private key components respectively as ASN .1 INTEGERs.

This is an example how to export/import DSA private keys in openssl format:

from Crypto.PublicKey import DSA
from Crypto.Util import asn1

key = DSA.generate(1024)

# export

seq = asn1.DerSequence()
seq[:] = [ 0, key.p, key.q, key.g, key.y, key.x ]

exported_key = "-----BEGIN DSA PRIVATE KEY-----\n%s-----END DSA PRIVATE KEY-----" % seq.encode().encode("base64")

print exported_key

# import

seq2 = asn1.DerSequence()
data = "\n".join(exported_key.strip().split("\n")[1:-1]).decode("base64")
seq2.decode(data)
p, q, g, y, x = seq2[1:]

key2 = DSA.construct((y, g, p, q, x))

assert key == key2
abbot
  • 27,408
  • 6
  • 54
  • 57
  • Thank for your valuable example. I just want to generate the key pairs from Python so that they can be used with OpenSSH. I was looking after the _public key part_. For the public key, I think that I need the **SubjectPublicKeyInfo** as this is what I read from the man page `When used with a public key it uses a SubjectPublicKeyInfo structure: it is an error if the key is not DSA.` Thanks again! – Adi Roiban May 11 '11 at 10:58
  • I found the public key format in the Twisted code : http://twistedmatrix.com/trac/browser/tags/releases/twisted-11.0.0/twisted/conch/ssh/keys.py#L93 – Adi Roiban May 11 '11 at 11:12
  • In this case may be you should check with [paramiko](http://www.lag.net/paramiko/) sources. – abbot May 11 '11 at 11:33
  • For now Twisted.conch.ssh.key solved my problem. Your answer did not directly solved my problem, but it gave me a good start and motivation to look around for documentation :) – Adi Roiban May 11 '11 at 13:30
  • [keyczar](http://keyczar.org) has some more detailed conversion routines in [keyczar.util](http://www.keyczar.org/pydocs/keyczar.util-module.html) – Hans-Christoph Steiner Nov 30 '11 at 21:32
  • For RSA use seq[:] = [ 0, key.n, key.e ] – themadmax Aug 27 '18 at 11:32