Cracker password SHA256 - forza bruta
Ho scritto un cracker di password SHA256. Inizialmente ho usato gli elenchi per memorizzare le informazioni list1.txte list2.txtalla fine avrei avuto sovraccarichi di memoria. Quindi ora uso i file. Ho notato che quando ho effettuato questa transizione, la velocità del programma si è ridotta enormemente. C'è un modo per ottimizzare la velocità di questa programmazione senza incorrere in problemi di sovraccarico di memoria?
Grazie
import hashlib
import time
import os
def extract_password(fname):
if fname == 0:
filename = "list2.txt"
else:
filename = "list1.txt"
for line in open(filename, "r"):
yield line.strip()
def save_password(fname, password):
if fname == 0:
filename = "list1.txt"
else:
filename = "list2.txt"
file = open(filename, "a")
file.write(password)
file.write("\n")
file.close()
def next_password(lsta, item,next_char, secure_password):
found = 0
guess = item + chr(next_char)
if hash_password(guess) == secure_password:
print(guess)
found = 1
save_password(lsta, guess)
return found
def hash_password(pwrd):
#Generates hash of original password
pwrd = pwrd.encode("UTF-8")
password = hashlib.sha256()
password.update(pwrd)
return password.hexdigest()
def delete_file(ltsa):
try:
if ltsa == 1:
os.remove("list2.txt")
else:
os.remove("list1.txt")
except:
pass
def reset_file_status():
try:
os.remove("list2.txt")
os.remove("list1.txt")
except:
pass
def find_password(secure_password):
#Brute force to find original password
found = 0
lsta = 1
for length in range(1, 15):
if found == 1: break
lsta = lsta^1
delete_file(lsta)
for next_char in range(65, 123):
if found == 1: break
if length == 1:
found = next_password(lsta, "", next_char, secure_password)
if found == 1: break
else:
for item in extract_password(lsta):
found = next_password(lsta, item, next_char, secure_password)
if found == 1: break
if __name__ == "__main__":
reset_file_status()
start = time.time()
secure_password = hash_password("AAAA")
find_password(secure_password)
print(f"{(time.time() - start)} seconds")
Risposte
L'ottimizzazione che stai cercando è molto semplice:
chiedi a te stesso: cosa devo mantenere?
La risposta: sto controllando solo l'ipotesi della password.
Non è necessario memorizzare tutte le vecchie ipotesi, quindi non sono necessari file o elenchi enormi.
Tutto ciò di cui hai veramente bisogno è una stringa che continuerai ad aggiornare.
Per visualizzarlo, pensa alla tua stringa come a un numero crescente, con ogni lettera che è una cifra di 58 in base.
Adesso. tutto ciò di cui hai veramente bisogno è fare un +1 sulla prima cifra, controllando il carry e aggiornando le cifre successive se necessario proprio come al solito aggiunta.
Sfortunatamente, le stringhe Python non consentono l'assegnazione per indice, ma supportano lo slicing .
Ecco una funzione che genererebbe password sequenziali che attraversano tutte le lettere e aumentano la lunghezza secondo necessità (una password per chiamata!):
def make_next_guess(guess):
carry = 1
next_guess = guess
for i in range(len(guess)):
cur_char = ord(guess[i]) + carry
if cur_char > ord('z'):
cur_char = ord('A')
carry = 1
else:
carry = 0
next_guess = next_guess[:i] + chr(cur_char) + guess[i + 1:]
if carry == 0:
break
if carry = 1:
next_guess += 'A'
return next_guess
Con questo puoi usare un loop per tutte le possibilità fino alla lunghezza massima:
guess = 'A'
for _ in range(58 ** 14): #password maximum length 14 and there are 58 characters that can be used
if hash_password(guess) == secure_password:
print(guess)
break
guess = make_next_guess(guess)