1+ import os
2+ import sys
3+ import hmac
4+ import base64
5+ import hashlib
6+ import argparse
7+
8+ def checksum (hash , seed = None ):
9+ hashs = {
10+ "md5" : hashlib .md5 ,
11+ "sha1" : hashlib .sha1 ,
12+ "sha224" : hashlib .sha224 ,
13+ "sha256" : hashlib .sha256 ,
14+ "sha384" : hashlib .sha384 ,
15+ "sha512" : hashlib .sha512
16+ }
17+ method = hashs .get (hash , hashlib .md5 )()
18+ if seed is not None :
19+ method .update (seed .encode ("utf-8" ))
20+ else :
21+ method .update (os .urandom (32 ))
22+ return method .hexdigest ()
23+
24+ def sign (hash , message , secret ):
25+ hashs = {
26+ "md5" : hashlib .md5 ,
27+ "sha1" : hashlib .sha1 ,
28+ "sha224" : hashlib .sha224 ,
29+ "sha256" : hashlib .sha256 ,
30+ "sha384" : hashlib .sha384 ,
31+ "sha512" : hashlib .sha512
32+ }
33+ method = hashs .get (hash , hashlib .md5 )()
34+ digest = hmac .new (secret .encode ("utf-8" ),
35+ msg = message .encode (),
36+ digestmod = hashs .get (hash , hashlib .md5 )).digest ()
37+ signature = base64 .b64encode (digest ).decode ("utf-8" )
38+ return signature
39+
40+ def verify (hash , input , check , secret = None ):
41+ challenge = None
42+ if secret is not None :
43+ challenge = sign (hash , input , secret )
44+ else :
45+ challenge = checksum (hash , input )
46+ return "Valid! :D" if challenge == check else "Invalid :("
47+
48+ def main ():
49+ description = "Checksum tool to generate, sign, and verify"
50+ parser = argparse .ArgumentParser (description = description )
51+ parser .add_argument ("-g" , "--generate" , dest = "generate" ,
52+ action = "store_true" , help = "Generates checksum" )
53+ parser .add_argument ("-s" , "--sign" , dest = "sign" , default = None ,
54+ help = "Signs input using HMAC" )
55+ parser .add_argument ("-H" , "--hash" , dest = "hash" , default = "md5" ,
56+ help = "Hash method (md5, sha1, sha224, sha256, sha384, sha512)" )
57+ parser .add_argument ("-v" , "--verify" , dest = "verify" , default = None ,
58+ help = "Checksum or signature used to verify against file / stdin" )
59+ parser .add_argument ("-f" , "--file" , dest = "file" ,
60+ type = argparse .FileType ("r" ), default = sys .stdin ,
61+ help = "File / stdin to create checksum, make signature, or verify from" )
62+ arguments = parser .parse_args ()
63+
64+ if arguments .verify is not None :
65+ if not arguments .file :
66+ print ("Missing input to generate checksum from" )
67+ sys .exit (1 )
68+ if arguments .sign is not None :
69+ print (verify (arguments .hash , arguments .file .read (),
70+ arguments .verify , arguments .sign ))
71+ return
72+ else :
73+ print (verify (arguments .hash , arguments .file .read (),
74+ arguments .verify ))
75+ return
76+ elif arguments .generate :
77+ if not arguments .file :
78+ print ("Missing input to generate checksum from" )
79+ sys .exit (1 )
80+ print (checksum (arguments .hash , arguments .file .read ()))
81+ return
82+ elif arguments .sign is not None :
83+ if not arguments .file :
84+ print ("Missing input to generate checksum from" )
85+ sys .exit (1 )
86+ print (sign (arguments .hash , arguments .file .read (), arguments .sign ))
87+ return
88+ print ("Missing function (-g, -s, -v)" )
89+ sys .exit (1 )
90+
91+ if __name__ == "__main__" :
92+ main ()
0 commit comments