Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions scripts/checksum/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Checksum

This script can generate checksums from md5, sha1, sha224, sha256, sha384, and sha512.
Additionally, for another layer of secret it can create signed checksums using HMAC and a provided secret.
Lastly, to provide actual value to the script it can also verify if a checksum matches the file it was generated from.

Examples:

Generate a sha1 checksum
```
python checksum.py -H sha1 -f test.txt -g
# b29d28bc5239dbc2689215811b2a73588609f301
```

Generate a signature
```
python checksum.py -f test.txt -s secret
# 3YYMCthY4hFxQj1wPF3uAg==
```

Verify a checksum
```
python -H sha1 -f test.txt -v b29d28bc5239dbc2689215811b2a73588609f301
```

Verify a signature
```
python -f test.txt -s secret -v 3YYMCthY4hFxQj1wPF3uAg==
```
92 changes: 92 additions & 0 deletions scripts/checksum/checksum.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import os
import sys
import hmac
import base64
import hashlib
import argparse

def checksum(hash, seed=None):
hashs = {
"md5": hashlib.md5,
"sha1": hashlib.sha1,
"sha224": hashlib.sha224,
"sha256": hashlib.sha256,
"sha384": hashlib.sha384,
"sha512": hashlib.sha512
}
method = hashs.get(hash, hashlib.md5)()
if seed is not None:
method.update(seed.encode("utf-8"))
else:
method.update(os.urandom(32))
return method.hexdigest()

def sign(hash, message, secret):
hashs = {
"md5": hashlib.md5,
"sha1": hashlib.sha1,
"sha224": hashlib.sha224,
"sha256": hashlib.sha256,
"sha384": hashlib.sha384,
"sha512": hashlib.sha512
}
method = hashs.get(hash, hashlib.md5)()
digest = hmac.new(secret.encode("utf-8"),
msg=message.encode(),
digestmod=hashs.get(hash, hashlib.md5)).digest()
signature = base64.b64encode(digest).decode("utf-8")
return signature

def verify(hash, input, check, secret=None):
challenge = None
if secret is not None:
challenge = sign(hash, input, secret)
else:
challenge = checksum(hash, input)
return "Valid! :D" if challenge == check else "Invalid :("

def main():
description = "Checksum tool to generate, sign, and verify"
parser = argparse.ArgumentParser(description=description)
parser.add_argument("-g", "--generate", dest="generate",
action="store_true", help="Generates checksum")
parser.add_argument("-s", "--sign", dest="sign", default=None,
help="Signs input using HMAC")
parser.add_argument("-H", "--hash", dest="hash", default="md5",
help="Hash method (md5, sha1, sha224, sha256, sha384, sha512)")
parser.add_argument("-v", "--verify", dest="verify", default=None,
help="Checksum or signature used to verify against file / stdin")
parser.add_argument("-f", "--file", dest="file",
type=argparse.FileType("r"), default=sys.stdin,
help="File / stdin to create checksum, make signature, or verify from")
arguments = parser.parse_args()

if arguments.verify is not None:
if not arguments.file:
print("Missing input to generate checksum from")
sys.exit(1)
if arguments.sign is not None:
print(verify(arguments.hash, arguments.file.read(),
arguments.verify, arguments.sign))
return
else:
print(verify(arguments.hash, arguments.file.read(),
arguments.verify))
return
elif arguments.generate:
if not arguments.file:
print("Missing input to generate checksum from")
sys.exit(1)
print(checksum(arguments.hash, arguments.file.read()))
return
elif arguments.sign is not None:
if not arguments.file:
print("Missing input to generate checksum from")
sys.exit(1)
print(sign(arguments.hash, arguments.file.read(), arguments.sign))
return
print("Missing function (-g, -s, -v)")
sys.exit(1)

if __name__ == "__main__":
main()