Repository navigation
Expand file tree
/
Copy pathhash_utils.py
More file actions
91 lines (74 loc) · 3.15 KB
/
Copy pathhash_utils.py
File metadata and controls
91 lines (74 loc) · 3.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# hash_utils.py — Hash identification and analysis utilities
# Useful companion to Decryptor.py's hash_check function
import hashlib
import re
HASH_PATTERNS = {
"MD5": (r"^[a-fA-F0-9]{32}$", 32),
"SHA1": (r"^[a-fA-F0-9]{40}$", 40),
"SHA224": (r"^[a-fA-F0-9]{56}$", 56),
"SHA256": (r"^[a-fA-F0-9]{64}$", 64),
"SHA384": (r"^[a-fA-F0-9]{96}$", 96),
"SHA512": (r"^[a-fA-F0-9]{128}$", 128),
"SHA3-256": (r"^[a-fA-F0-9]{64}$", 64),
"SHA3-512": (r"^[a-fA-F0-9]{128}$", 128),
"RIPEMD-160": (r"^[a-fA-F0-9]{40}$", 40),
"BLAKE2b": (r"^[a-fA-F0-9]{128}$", 128),
"BLAKE2s": (r"^[a-fA-F0-9]{64}$", 64),
"CRC32": (r"^[a-fA-F0-9]{8}$", 8),
}
def identify_hash(hash_str):
"""Identify possible hash type(s) based on length and character set."""
hash_str = hash_str.strip()
candidates = []
for name, (pattern, _) in HASH_PATTERNS.items():
if re.match(pattern, hash_str):
candidates.append(name)
return candidates if candidates else ["Unknown / Not a hex hash"]
def generate_all_hashes(text):
"""Generate all supported hashes for a given plaintext."""
data = text.encode()
return {
"MD5": hashlib.md5(data).hexdigest(),
"SHA1": hashlib.sha1(data).hexdigest(),
"SHA224": hashlib.sha224(data).hexdigest(),
"SHA256": hashlib.sha256(data).hexdigest(),
"SHA384": hashlib.sha384(data).hexdigest(),
"SHA512": hashlib.sha512(data).hexdigest(),
"SHA3-256": hashlib.sha3_256(data).hexdigest(),
"SHA3-512": hashlib.sha3_512(data).hexdigest(),
"BLAKE2b": hashlib.blake2b(data).hexdigest(),
"BLAKE2s": hashlib.blake2s(data).hexdigest(),
}
def wordlist_attack(hash_str, wordlist, algorithm="md5"):
"""
Attempt to crack a hash using a wordlist (list of strings).
Returns the matched plaintext or None.
"""
hash_str = hash_str.strip().lower()
algo = algorithm.lower().replace("-", "")
hasher = getattr(hashlib, algo, None)
if not hasher:
raise ValueError(f"Unsupported algorithm: {algorithm}")
for word in wordlist:
if hasher(word.encode()).hexdigest() == hash_str:
return word
return None
def compare_hashes(hash1, hash2):
"""Constant-time hash comparison to prevent timing attacks."""
import hmac
return hmac.compare_digest(hash1.lower(), hash2.lower())
if __name__ == "__main__":
sample = "5d41402abc4b2a76b9719d911017c592" # MD5 of "hello"
print("=== Hash Identification ===")
print(f"Possible types: {identify_hash(sample)}")
print("\n=== Generate All Hashes for 'hello' ===")
for algo, digest in generate_all_hashes("hello").items():
print(f"{algo}: {digest}")
print("\n=== Wordlist Attack ===")
words = ["password", "hello", "admin", "secret", "neon"]
result = wordlist_attack(sample, words, algorithm="md5")
print(f"Cracked: {result}" if result else "Not found in wordlist")
print("\n=== Compare Hashes ===")
h1 = hashlib.md5(b"hello").hexdigest()
h2 = hashlib.md5(b"hello").hexdigest()
print(f"Match: {compare_hashes(h1, h2)}")