Skip to content

Instantly share code, notes, and snippets.

@Commod0re
Created November 8, 2017 18:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Commod0re/7560faa37a8a478d6792a1be257b83b8 to your computer and use it in GitHub Desktop.
Save Commod0re/7560faa37a8a478d6792a1be257b83b8 to your computer and use it in GitHub Desktop.
build a key from existing values
#!/usr/bin/env python
from datetime import datetime
from pgpy import PGPKey, PGPUID, PGPSignature
from pgpy.constants import PubKeyAlgorithm
from pgpy.packet import PubKeyV4
from pgpy.packet.types import MPI
def assemble_rsa_pubkey(n, e, created):
# WARNING: HERE BE DRAGONS
# these properties are not considered part of the API and may change in the future
# there will be actual API added to accomplish this more conveniently because it is useful, so stay tuned for that
key = PGPKey()
# for a privkey use PrivKeyV4
key._key = PubKeyV4()
# the creation date in the key packet affects the key fingerprint,
# but this can be omitted if there's no need to maintain that,
# e.g. if the key did not previously exist as an OpenPGP key
key._key.created = created
key._key.pkalg = PubKeyAlgorithm.RSAEncryptOrSign
# the keymaterial fields differ based on what key algorithm is in use -
# setting _key. pkalg instantiates the correct class for _key.keymaterial.
# See pgpy/packet/fields.py (look at the __pubfields__ and __privfields__
# properties, or the _generate method for the *Priv class that matches
# your algorithm) for what fields your key algorithm needs
key._key.keymaterial.n = MPI(n)
key._key.keymaterial.e = MPI(e)
# if we'd used PrivKeyV4 instead, for RSA, we'd also need to set
# d, p, q, and u, where u can be derived (see pgpy.packet.fields.RSAPriv._generate)
# for a private key, call key._key.keymaterial._compute_chksum() here
key._key.update_hlen()
return key
if __name__ == '__main__':
# WARNING: these small values are here for the sake of the example being readable
# please don't use such small RSA keys for anything more important than example code
n = 8503889732522138487695939124253595708816839007885044584145451609214205150733473557520173387766932445639160093079626991637560423848427124071620710948292389
e = 65537
uid = PGPUID.new("Pain Janksson")
key = assemble_rsa_pubkey(n, e, datetime(2017, 11, 8, 18, 11, 42, 204921))
key.add_uid(uid, selfsign=False)
# confirm that it worked
# should be: 11EF 98A4 06EB 4DCB D41A 979E 6E45 A6D2 03C1 D5A1
print(key.fingerprint)
sig = PGPSignature.from_blob('-----BEGIN PGP SIGNATURE-----\nVersion: PGPy v0.4.4\n\nwlwEAAELAAYFAloDSecACgkQbkWm0gPB1aGO4QH/Qks4Kfx1qhBd0Djz19PExrSM\nP8XFSyHfrZQ2qFdCU5HvF6B9NHa4lve+AFg3NnsRaxjl1eENrQCKZ+zl8xwdDw==\n=VYVv\n-----END PGP SIGNATURE-----\n')
sv = key.verify("sign this!", sig)
print(sv)
@anarcat
Copy link

anarcat commented Nov 10, 2017

fwiw, here's a crossref to the issue this is for: SecurityInnovation/PGPy#220

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment