GNU Privacy Guard (GPG) Signatures with PythonThe GNU Privacy Guard (GPG) is a program that is based on OpenPGP and can generation a keys pairs, encrypt and decrypt data, and digitally sign files and verify digital signatures. This page uses Version 2.4.0. It supports the public key methods of RSA, ELG, DSA, ECDH, ECDSA, and EDDSA. In this case we will generate RSA, ECDSA and EdDSA signatures. |
Meet GPG
It was Phil Zimmerman who created the PGP (Pretty Good Privacy), and which has advanced to the GNU Privacy Guard (GPG). Overall GPG is a program that is based on OpenPGP and can generate keys pairs, encrypt and decrypt data, and digitally sign files and verify digital signatures. This page uses Version 2.4.0. It supports the public key methods of RSA, ELG, DSA, ECDH, ECDSA, and EDDSA. Also symmetric key ciphers of IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH, CAMELLIA128, CAMELLIA192, and CAMELLIA256, along with SHA1, RIPEMD160, SHA256, SHA384, SHA512, and SHA224. The compression methods supported are ZIP, ZLIB, and BZIP2.
For this we can install GPG [here], and which should install an executable (and a standalone version of GPG). If possible, GPG Version 2 is the best, as it supports a range of elliptic curve signatures, including ECDSA and EdDSA. Next we can link to the executable with Python GnuPG [here].
To create a key pair, we need: the type (RSA, ECDSA or EdDSA), the user name, their email address, and a passphrase. If we have an RSA key pair, we define the size of the keys, such as for RSA-1024, RSA-2048, and RSA-4096. If we have ECDSA, we need to define the curve, such as secp256k1 or NIST P256. For EdDSA, we normally define the curve as Curve 25519 (and use Ed25519 for the keys). The following code thus generates a signature for a message and verifies it:
import gnupg import sys gpg = gnupg.GPG(gnupghome="c:\\gpg") enc="rsa-1024" password="password" user="Fred Bloggs" email="[email protected]" message="Hello" if (len(sys.argv)>1): enc=str(sys.argv[1]) if (len(sys.argv)>2): password=str(sys.argv[2]) if (len(sys.argv)>3): user=str(sys.argv[3]) if (len(sys.argv)>4): email=str(sys.argv[4]) if (len(sys.argv)>5): message=str(sys.argv[5]) input_data = gpg.gen_key_input(key_type="RSA",key_length=1024,passphrase=password,name_real=user,name_email=email) if (enc=="ecdsa-p256"): input_data = gpg.gen_key_input(key_type="ECDSA",key_curve='nistp256',passphrase=password,name_real=user,name_email=email) if (enc=="ecdsa-p384"): input_data = gpg.gen_key_input(key_type="ECDSA",key_curve='nistp384',passphrase=password,name_real=user,name_email=email) if (enc=="ecdsa-p521"): input_data = gpg.gen_key_input(key_type="ECDSA",key_curve='nistp521',passphrase=password,name_real=user,name_email=email) if (enc=="ecdsa-secp256k1"): input_data = gpg.gen_key_input(key_type="ECDSA",key_curve='secp256k1',passphrase=password,name_real=user,name_email=email) if (enc=="eddsa"): input_data = gpg.gen_key_input(key_type="EDDSA",key_curve='ed25519',passphrase=password,name_real=user,name_email=email) if (enc=="rsa-1024"): input_data = gpg.gen_key_input(key_type="RSA",key_usage='sign',key_length=1024,passphrase=password,name_real=user,name_email=email) if (enc=="rsa-2048"): input_data = gpg.gen_key_input(key_type="RSA",key_length=2048,passphrase=password,name_real=user,name_email=email) if (enc=="rsa-3072"): input_data = gpg.gen_key_input(key_type="RSA",key_length=3072,passphrase=password,name_real=user,name_email=email) key = gpg.gen_key(input_data) fp = key.fingerprint print ("Key ID: ",fp) print ("Type: ",enc) signed_data = gpg.sign(message.encode(),keyid=fp,passphrase=password) print (str(signed_data).replace(chr(13),'')) ver = gpg.verify(signed_data.data) if (ver.returncode==0): print ("Signature verified") print("\n\n\n") ascii_armored_public_keys = gpg.export_keys(fp) print("Public key:\n",ascii_armored_public_keys.replace(chr(13),'')) ascii_armored_private_keys = gpg.export_keys(fp,True,passphrase=password) print("Private key:\n",ascii_armored_private_keys.replace(chr(13),'')) print("Private key deleted: ",gpg.delete_keys(fp,True,passphrase=password)) print("Public key deleted: ",gpg.delete_keys(fp))
A sample signature for ECDSA is:
Key ID: C9664F695E681E4A9AF40E82297B2622D6ADF08B Type: ecdsa-p256 -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 Hello, how are you? -----BEGIN PGP SIGNATURE----- iHUEARMIAB0WIQTJZk9pXmgeSpr0DoIpeyYi1q3wiwUCY+v09AAKCRApeyYi1q3w i0GbAP92lnyuSgn2hxyY6vhmY9uROErItD8X7BPnE6EBpWL7PgD/dR2DAqOstBbM ctVaa72nUQnenxvV5Ml0obRFgK6nswI= =+1J3 -----END PGP SIGNATURE----- Signature verified Public key: -----BEGIN PGP PUBLIC KEY BLOCK----- mFIEY+v09BMIKoZIzj0DAQcCAwS8W60lzrJMAUvaZfkWgNLqV73+LDb0RuIwC6ST BT2PXWaqDJ9fsLG8K9fgN8AWxcA/180yobkSiQ/Uqv8FUXOitBtGcmVkIEJsb2dn cyA8ZnJlZEBob21lLmNvbT6IkwQTEwgAOxYhBMlmT2leaB5KmvQOgil7JiLWrfCL BQJj6/T0AhsjBQsJCAcCAiICBhUKCQgLAgQWAgMBAh4HAheAAAoJECl7JiLWrfCL 3dUBAKv/GRlRigZvFrzZUvM+8SjOXS9Cid/8tjHJwiX2LucoAP9nhsG5egiyIlLO Jbae1RAQpURsJhe6hJyTdUj2qOfkpA== =gfrd -----END PGP PUBLIC KEY BLOCK----- Private key: -----BEGIN PGP PRIVATE KEY BLOCK----- lKUEY+v09BMIKoZIzj0DAQcCAwS8W60lzrJMAUvaZfkWgNLqV73+LDb0RuIwC6ST BT2PXWaqDJ9fsLG8K9fgN8AWxcA/180yobkSiQ/Uqv8FUXOi/gcDAo+C0lWUpbf8 ysZ0duPZ4/5jfJdUp8aFALGMEHnnAGtL26IQb7vw/A9DY83vVUKoOYxtpIOwBF3h MyD7CWu/5tozb+Jxg7FgKgEHS4eoDpW0G0ZyZWQgQmxvZ2dzIDxmcmVkQGhvbWUu Y29tPoiTBBMTCAA7FiEEyWZPaV5oHkqa9A6CKXsmItat8IsFAmPr9PQCGyMFCwkI BwICIgIGFQoJCAsCBBYCAwECHgcCF4AACgkQKXsmItat8Ivd1QEAq/8ZGVGKBm8W vNlS8z7xKM5dL0KJ3/y2McnCJfYu5ygA/2eGwbl6CLIiUs4ltp7VEBClRGwmF7qE nJN1SPao5+Sk =+SEa -----END PGP PRIVATE KEY BLOCK----- Private key deleted: ok Public key deleted: ok
and for RSA-2048
Key ID: 6EA920795B56C604A74EF710D48572828F63D329 Type: rsa-2048 -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 Hello, how are you? -----BEGIN PGP SIGNATURE----- iQEzBAEBCAAdFiEEbqkgeVtWxgSnTvcQ1IVygo9j0ykFAmPr9TUACgkQ1IVygo9j 0yl0YwgAnRpW1cojfPg5Q/ygK7v/TODx8kahURNPMnuXxi/uzyrbdRBmMWKICdyD pWCqOqgLTeT1954+aEWwxnOY3sOiTXUyV2c2JSzN9+Lx2uoQFShBUjQwdNDnwmIl ohBDA3TNyMxXIW4A0xsSqFaILpzC7wIvaPudh51Bo8krl3zVoKEjdx5MhK+a/yL+ MGn83pn03RZ+ex8FaG+rtLnQgagay+9ETT72x46JZvBvIMmhGiWtv/ZNld9IRkMy iy5OuuzYLu9Hq7jaqNj0YndcwARdDEUQBCap0mZxQh+z1e5vOvLAl4g6nlsdBPgY wnZgjhOrdSnjtl7Z/moxHXsOaRuGFw== =pnSq -----END PGP SIGNATURE----- Signature verified Public key: -----BEGIN PGP PUBLIC KEY BLOCK----- mQENBGPr9TMBCADTfrIIxHeGPLbzMRx1F+atAMsyvmqY7RqBdFrB+41MEkhTk1bC 42iTZif/w3sF0vWSWMEAHmM0q4+6KAuDhil1MnCtCSOChABH8pmO3GZvPGbP1rv9 RqvOyXvPgVfrUUcmFdizkR/HKd5VTW0pfQDZHWG2KuE/rYtYIlOpzwGKx+D79GoB 8MxiD3vLpA5v0GC/LSFx+KxU94BbElB+nxkEC777aMUQrAFyyzit9Niu6LYxBaXN xbcNm/Ac2huekNITWgBrohSeS62gpG5cKO4ZDrD8vLOazV+a8NKPsITi4pDJU19Y 6pBvDtIo7vx8pKDJ1rrDBLDR36ZeCLk+xDBbABEBAAG0G0ZyZWQgQmxvZ2dzIDxm cmVkQGhvbWUuY29tPokBUQQTAQgAOxYhBG6pIHlbVsYEp073ENSFcoKPY9MpBQJj 6/UzAhsvBQsJCAcCAiICBhUKCQgLAgQWAgMBAh4HAheAAAoJENSFcoKPY9Mp93cI ALC5nAaRhvk8w9KUxW8UaLKiA/eoWOrHPhWzU1+v0Pi/N7zQM3e6Fq4vJqAOIanZ rGsIwOgSDDi6yyGBktE6R5gu3iP0/bOnc7FDf6x3ubNl9xnhBMz13Vovh2kQmwsl A+4P/HWfo9o2yCQlXprO2k1SlpJFGzqT7Da4eVJK8FLdNP7r+3HCXWGpYFguOoVc sa3LVMSRTgnkKqRzVu0kS8tw1csAASowYlQRvQp7Pw5tTRAo97TVZ2vFHv3KR1fN 0WvjQSTM2Alpq5y0L1QKvhBTHldQzH+DGyydySL3OF8q7srOlIZLmYfhHUvZwSbk BDhOPvrRgLNYeFQyL86yTrI= =+TCY -----END PGP PUBLIC KEY BLOCK----- Private key: -----BEGIN PGP PRIVATE KEY BLOCK----- lQPGBGPr9TMBCADTfrIIxHeGPLbzMRx1F+atAMsyvmqY7RqBdFrB+41MEkhTk1bC 42iTZif/w3sF0vWSWMEAHmM0q4+6KAuDhil1MnCtCSOChABH8pmO3GZvPGbP1rv9 RqvOyXvPgVfrUUcmFdizkR/HKd5VTW0pfQDZHWG2KuE/rYtYIlOpzwGKx+D79GoB 8MxiD3vLpA5v0GC/LSFx+KxU94BbElB+nxkEC777aMUQrAFyyzit9Niu6LYxBaXN xbcNm/Ac2huekNITWgBrohSeS62gpG5cKO4ZDrD8vLOazV+a8NKPsITi4pDJU19Y 6pBvDtIo7vx8pKDJ1rrDBLDR36ZeCLk+xDBbABEBAAH+BwMCUQCp2yQaLEHKx+YZ lj0DUnitvWRD1NnFubqkTv453qdzYqOlFZsPuJd+oTapluHeCw7di+1b0rI7LMug xmCZHYmMR0zFm//bccd3a/nOHv5zMocDb9zh/Uc+dTiqql+925aBVyzoXVaGFWIi QQ9i2byNhyuAJqW3wKC5J6y8lnIi4qxJzgeuWFtmCks1NMkP8ftUw4my2pXqEu1/ vcoWTmEdcNm9ooIfDNGi1Q3BgcYdByGm/++9qME64aLpBXf1IIbSmHhYBsYge4DB 0LTppD4nGpO8vAsIvdgwVClmHHzlnpA7rZzbB1gv/LI08tz6dYIm6ItHme079VjI S/EacSygupg0f7oB0XMlcvTzJeHaLgSe1Sc9zv+XQodxX+eNnCyUb+47Ni85lxPY q4/FR39ydUzmqU7wc05WJOX6zuk4PzGH+hq/TOD23WipumuY+YOjmYxwSr5gnwMR x2QU901PDiAcrXk0ZI1qzY9+fb8LHShV+vAj4kbOBxkPr1dQGBjFSflnNLdxYqg6 yRpJhPL+yLo3LZXlvtST9ftrqIbaKhnhdK1po31evxptNz9WBEeI6BxrJwclVdoF ryuBgpOqjurh71/CEAKeruxHng2Ym1xNtFaISvanthPQGTWvuiEliXxd6Xo5jIa0 iKJwpMEbBGHE6BBZ80BmWNWyJm8MYz0A4w5ZWMU1+AezPBGYkWHpf4LfqBO3oQoZ thC7L2JkxBYJZ+GXSXV/raY1siatjL1zFJuDhg4Cfq1zK/apgNIhor9PGrUHG82K ianI+zCXQdLHkB4+sqaQCXtbtkdC1XbWRfVKV7u4T2eTzaQf9uduZPxGxvOMbuUZ 4ImxuOzEAoLYXd5LxdzQXP16I8LW2AeWCtx7Wq38vmwU8t3oIOojbEWrejAnjeYI Kx/JHJt/9vaTtBtGcmVkIEJsb2dncyA8ZnJlZEBob21lLmNvbT6JAVEEEwEIADsW IQRuqSB5W1bGBKdO9xDUhXKCj2PTKQUCY+v1MwIbLwULCQgHAgIiAgYVCgkICwIE FgIDAQIeBwIXgAAKCRDUhXKCj2PTKfd3CACwuZwGkYb5PMPSlMVvFGiyogP3qFjq xz4Vs1Nfr9D4vze80DN3uhauLyagDiGp2axrCMDoEgw4usshgZLROkeYLt4j9P2z p3OxQ3+sd7mzZfcZ4QTM9d1aL4dpEJsLJQPuD/x1n6PaNsgkJV6aztpNUpaSRRs6 k+w2uHlSSvBS3TT+6/txwl1hqWBYLjqFXLGty1TEkU4J5Cqkc1btJEvLcNXLAAEq MGJUEb0Kez8ObU0QKPe01WdrxR79ykdXzdFr40EkzNgJaauctC9UCr4QUx5XUMx/ gxssncki9zhfKu7KzpSGS5mH4R1L2cEm5AQ4Tj760YCzWHhUMi/Osk6y =mCsw -----END PGP PRIVATE KEY BLOCK----- Private key deleted: ok Public key deleted: ok