¿Cómo corregir TypeError: los objetos Unicode deben codificarse antes del hash?


295

Tengo este error:

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

cuando intento ejecutar este código 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()

Encontré que abrir un archivo con 'rb' ayudó a mi caso.
dlamblin

Respuestas:


299

Probablemente esté buscando una codificación de caracteres wordlistfile.

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

O, si está trabajando línea por línea:

line.encode('utf-8')

3
open(wordlist,"r",encoding='utf-8')por qué usar open con codificación específica, la codificación se especifica el códec de decodificación, sin esta opción, utiliza codificación dependiente de la plataforma.
Tanky Woo

129

Debe tener que definir encoding formatcomo utf-8, intente esta manera fácil,

Este ejemplo genera un número aleatorio usando el algoritmo SHA256:

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

18

Para almacenar la contraseña (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
Esta línea hace que la contraseña sea imposible de usar. password_salt = os.urandom (32) .hex () Debe ser un valor conocido fijo pero puede ser secreto solo para el servidor. Corrígeme o adáptalo a tu código.
Yash

1
Estoy de acuerdo con @Yash Usted tiene una sal única que usa para cada hash (no la mejor), o si genera una sal aleatoria para cada hash, debe almacenarla con el hash para usarla más tarde para compararla
Carson Evans

15

El error ya dice lo que tienes que hacer. MD5 funciona en bytes, por lo que debe codificar la cadena Unicode en bytes, por ejemplo, con line.encode('utf-8').


11

Por favor, eche un vistazo primero a esa respuesta.

Ahora, el mensaje de error es clara: sólo se puede utilizar bytes, no cadenas de Python (lo que solía ser unicodeen Python <3), así que hay que codificar las cadenas con su codificación preferida: utf-32, utf-16, utf-8o incluso uno de los restringida 8- codificaciones de bits (lo que algunos podrían llamar páginas de códigos).

Python 3 decodifica automáticamente los bytes de su archivo de lista de palabras en Unicode a medida que lee el archivo. Te sugiero que hagas:

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

para que los datos codificados enviados al algoritmo md5 se codifiquen exactamente como el archivo subyacente.


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

6

Puede abrir el archivo en modo binario:

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

codificar esta línea me lo arregló.

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

0

Si es una cadena de una sola línea. envuélvala con b o B. ej .:

variable = b"This is a variable"

o

variable2 = B"This is also a variable"

-3

Este programa es la versión mejorada y sin errores del cracker MD5 anterior que lee el archivo que contiene la lista de contraseñas hash y lo compara con palabras hash de la lista de palabras del diccionario de inglés. Espero que sea útil.

Descargué el diccionario de inglés del siguiente enlace 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()
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.