Skip to content

Instantly share code, notes, and snippets.

@petri
Last active October 19, 2021 03:05
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save petri/650e27c712888bf4cb27c99716d36e45 to your computer and use it in GitHub Desktop.
Save petri/650e27c712888bf4cb27c99716d36e45 to your computer and use it in GitHub Desktop.
Single-file Python digital signature maker and checker
"""digicheck - create and verify signatures for files
Usage:
digicheck keys
digicheck public <keyfilename>
digicheck sign <filename> <keyfilename>
digicheck check <filename> <keyfilename> <signaturefilename>
digicheck (-h | --help)
digicheck --version
Use the command-line to first create a key pair, then a
signature for a file, and finally when you need to make
sure file has not been tampered with in the meantime,
check that the signatures are still equal.
Options:
-h --help Show this screen.
--version Show version.
"""
import sys
import docopt
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA
from Crypto import Random
def generate_keys():
random_generator = Random.new().read
key = RSA.generate(2048, random_generator)
return (key.exportKey(), key.publickey().exportKey())
def generate_hash(data):
return SHA256.new(data).digest()
def generate_signature(hash, key):
return key.sign(hash, '')
def verify_signature(hash, public_key, signature):
return public_key.verify(hash, signature)
if __name__ == "__main__":
args = docopt.docopt(__doc__)
if args["keys"]:
private, public = generate_keys()
keys = private + "\n\n" + public
print(keys.strip())
elif args["public"]:
with open(args["<keyfilename>"], "r") as keyfile:
public_key = keyfile.read().split("\n\n")[1]
print(public_key.strip())
elif args["sign"]:
with open(args["<filename>"], "rb") as signedfile:
hash = generate_hash(signedfile.read())
with open(args["<keyfilename>"], "r") as keyfile:
private_key = RSA.importKey(keyfile.read().split("\n\n")[0].strip())
print(generate_signature(hash, private_key)[0])
elif args["check"]:
with open(args["<filename>"], "rb") as signedfile:
hash = generate_hash(signedfile.read())
with open(args["<keyfilename>"], "r") as keyfile:
public_key = RSA.importKey(keyfile.read().split("\n\n")[1].strip())
with open(args["<signaturefilename>"], "r") as signaturefile:
signature = long(signaturefile.read())
if verify_signature(hash, public_key, (signature,)):
sys.exit("valid signature :)")
else:
sys.exit("invalid signature! :(")
@roderickvella
Copy link

keys = private + "\n\n" + public
TypeError: can't concat str to bytes

@mohitraj1
Copy link

keys = private + "\n\n" + public
TypeError: can't concat str to bytes

add decode('utf-8') to convert from byte to str when using Python3
keys = private.decode('utf-8') + "\n\n" + public.decode('utf-8')

@r0king
Copy link

r0king commented Jun 15, 2021

or just change '\n\n' to b'\n\n' thereof changing '\n\n' to byte

keys = private + b"\n\n" + public

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