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