Converting RSA public keys from OpenSSH into GPG
By JuroV on Thursday 2 June 2016, 22:07 - Programming - Permalink
All snippets are for Python 2.
Extracting parameters from SSH key.
The format is blessedly simple, so we can do this without additional libraries. For anything beyond, paramiko probably has it.
import base64 import struct import binascii def parsersakey(data): """:param data: RSA ssh pubkey string in rfc4253 ssh-rsa format :returns tuple exponent,modulus,comment. """ data = data.encode('ascii').split(b' ',2) x = base64.b64decode(data[1]) res = [] start = 0 while(start < len(x)-4): l = struct.unpack('>l',x[start:start+4])[0] r = struct.unpack('%ds' % l, x[start+4:start+4+l]) start = start+4+l res.append(r[0]) if(len(res) != 3): raise Exception("unexpected # of pieces: %d" % len(res)) if(start != len(x)): print("len got: %d expected: %d" % (len(x),start)) res.append(x[start:]) else: res.append([]) if res[0] != b"ssh-rsa": raise Exception("not rsa key: %s" % binascii.hexlify(res[0])) e = 0 for i in res[1]: e = (e<<8) + ord(i) N = 0 for i in res[2]: N = (N<<8) + ord(i) return (e,N,data[2] if len(data) == 3 else '')
Creating an PGP pubkey from the parameters
Uses PGPy 0.4.0. There is no API for creating keys from known RSA parameters, so the classes need some massaging. YMMV using other PGPy version.
The resulting key can be converted to rfc4880 form just by applying str() on it.
import pgpy from pgpy.packet.fields import RSAPub,MPI from pgpy.packet.packets import PubKeyV4 from pgpy.constants import PubKeyAlgorithm def custRSAPub(n,e): res = RSAPub() res.n = MPI(n) res.e = MPI(e) return res def custPubKeyV4(custkey): res = PubKeyV4() res.pkalg = PubKeyAlgorithm.RSAEncryptOrSign res.keymaterial = custkey res.update_hlen() return res def rsatogpg(e,N,name,**idargs): """ :param e,N: RSA parameters as Python integers or longints :param name: Identity name :param idargs: PGP Identity parameters, such as comment,email :return: PGPy pubkey object """ rsakey = custPubKeyV4(custRSAPub(N,e)) pgpkey = pgpy.PGPKey() pgpkey._key = rsakey uid = pgpy.PGPUID.new(name, **idargs) uid._parent = pgpkey pgpkey._uids.append(uid) return pgpkey