Comment corriger TypeError: les objets Unicode doivent être encodés avant le hachage?


295

J'ai cette erreur:

Traceback (most recent call last):
  File "python_md5_cracker.py", line 27, in <module>
  m.update(line)
TypeError: Unicode-objects must be encoded before hashing

lorsque j'essaie d'exécuter ce code en Python 3.2.2 :

import hashlib, sys
m = hashlib.md5()
hash = ""
hash_file = input("What is the file name in which the hash resides?  ")
wordlist = input("What is your wordlist?  (Enter the file name)  ")
try:
  hashdocument = open(hash_file, "r")
except IOError:
  print("Invalid file.")
  raw_input()
  sys.exit()
else:
  hash = hashdocument.readline()
  hash = hash.replace("\n", "")

try:
  wordlistfile = open(wordlist, "r")
except IOError:
  print("Invalid file.")
  raw_input()
  sys.exit()
else:
  pass
for line in wordlistfile:
  # Flush the buffer (this caused a massive problem when placed 
  # at the beginning of the script, because the buffer kept getting
  # overwritten, thus comparing incorrect hashes)
  m = hashlib.md5()
  line = line.replace("\n", "")
  m.update(line)
  word_hash = m.hexdigest()
  if word_hash == hash:
    print("Collision! The word corresponding to the given hash is", line)
    input()
    sys.exit()

print("The hash given does not correspond to any supplied word in the wordlist.")
input()
sys.exit()

J'ai trouvé que l'ouverture d'un fichier avec 'rb' avait aidé mon cas.
dlamblin

Réponses:


299

Il recherche probablement un codage de caractères à partir de wordlistfile.

wordlistfile = open(wordlist,"r",encoding='utf-8')

Ou, si vous travaillez ligne par ligne:

line.encode('utf-8')

3
open(wordlist,"r",encoding='utf-8')pourquoi utiliser open avec un codage spécifique, le codage est spécifié le codec de décodage, sans cette option, il utilise un codage dépendant de la plate-forme.
Tanky Woo

129

Vous devez avoir à définir encoding formatcomme utf-8, Essayez cette méthode simple,

Cet exemple génère un nombre aléatoire à l'aide de l'algorithme SHA256:

>>> import hashlib
>>> hashlib.sha256(str(random.getrandbits(256)).encode('utf-8')).hexdigest()
'cd183a211ed2434eac4f31b317c573c50e6c24e3a28b82ddcb0bf8bedf387a9f'

18

Pour enregistrer le mot de passe (PY3):

import hashlib, os
password_salt = os.urandom(32).hex()
password = '12345'

hash = hashlib.sha512()
hash.update(('%s%s' % (password_salt, password)).encode('utf-8'))
password_hash = hash.hexdigest()

1
Cette ligne rend le mot de passe impossible à utiliser. password_salt = os.urandom (32) .hex () Il doit s'agir d'une valeur connue fixe mais elle peut être secrète pour le serveur uniquement. Veuillez me corriger ou l'adapter à votre code.
Yash

1
Je suis d'accord avec @Yash Vous avez soit un seul sel que vous utilisez pour chaque hachage (pas le meilleur), ou si vous générez un sel aléatoire pour chaque hachage, vous devez le stocker avec le hachage pour l'utiliser à nouveau plus tard pour la comparaison
Carson Evans

15

L'erreur indique déjà ce que vous devez faire. MD5 fonctionne sur octets, vous devez donc encoder la chaîne Unicode en bytes, par exemple avec line.encode('utf-8').


11

Veuillez d'abord regarder cette réponse.

Maintenant, le message d'erreur est clair: vous ne pouvez utiliser octets, et non pas des chaînes Python (ce qui était unicodeen Python <3), de sorte que vous devez encoder les chaînes avec l' encodage préféré: utf-32, utf-16, utf-8ou même l' un des restreint 8- codages de bits (ce que certains pourraient appeler des pages de codes).

Les octets de votre fichier de liste de mots sont automatiquement décodés en Unicode par Python 3 lorsque vous lisez le fichier. Je vous suggère de faire:

m.update(line.encode(wordlistfile.encoding))

afin que les données encodées poussées vers l'algorithme md5 soient encodées exactement comme le fichier sous-jacent.


10
import hashlib
string_to_hash = '123'
hash_object = hashlib.sha256(str(string_to_hash).encode('utf-8'))
print('Hash', hash_object.hexdigest())

6

Vous pouvez ouvrir le fichier en mode binaire:

import hashlib

with open(hash_file) as file:
    control_hash = file.readline().rstrip("\n")

wordlistfile = open(wordlist, "rb")
# ...
for line in wordlistfile:
    if hashlib.md5(line.rstrip(b'\n\r')).hexdigest() == control_hash:
       # collision

6

encoder cette ligne l'a corrigé pour moi.

m.update(line.encode('utf-8'))

0

S'il s'agit d'une chaîne d'une seule ligne. enveloppez-le avec b ou B. Par exemple:

variable = b"This is a variable"

ou

variable2 = B"This is also a variable"

-3

Ce programme est la version sans bug et améliorée du cracker MD5 ci-dessus qui lit le fichier contenant la liste des mots de passe hachés et le vérifie par rapport au mot haché de la liste de mots du dictionnaire anglais. J'espère que c'est utile.

J'ai téléchargé le dictionnaire anglais à partir du lien suivant https://github.com/dwyl/english-words

# md5cracker.py
# English Dictionary https://github.com/dwyl/english-words 

import hashlib, sys

hash_file = 'exercise\hashed.txt'
wordlist = 'data_sets\english_dictionary\words.txt'

try:
    hashdocument = open(hash_file,'r')
except IOError:
    print('Invalid file.')
    sys.exit()
else:
    count = 0
    for hash in hashdocument:
        hash = hash.rstrip('\n')
        print(hash)
        i = 0
        with open(wordlist,'r') as wordlistfile:
            for word in wordlistfile:
                m = hashlib.md5()
                word = word.rstrip('\n')            
                m.update(word.encode('utf-8'))
                word_hash = m.hexdigest()
                if word_hash==hash:
                    print('The word, hash combination is ' + word + ',' + hash)
                    count += 1
                    break
                i += 1
        print('Itiration is ' + str(i))
    if count == 0:
        print('The hash given does not correspond to any supplied word in the wordlist.')
    else:
        print('Total passwords identified is: ' + str(count))
sys.exit()
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.