Como corrigir TypeError: os objetos Unicode devem ser codificados antes do hash?


295

Eu tenho este erro:

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

quando tento executar esse código no 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()

Achei que abrir um arquivo com 'rb' ajudou no meu caso.
dlamblin

Respostas:


299

Provavelmente, está procurando uma codificação de caracteres wordlistfile.

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

Ou, se você estiver trabalhando linha por linha:

line.encode('utf-8')

3
open(wordlist,"r",encoding='utf-8')Por que usar aberto com codificação específica, a codificação é especificada no codec de decodificação; sem essa opção, ele usa codificação dependente da plataforma.
Tanky Woo

129

Você deve definir encoding formatcomo utf-8, tente desta maneira fácil,

Este exemplo gera um número aleatório usando o algoritmo SHA256:

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

18

Para armazenar a senha (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 linha torna a senha impossível de usar. password_salt = os.urandom (32) .hex () Deve ter um valor conhecido fixo, mas pode ser secreto apenas para o servidor. Corrija-me ou adapte-o ao seu código.
Yash

1
Concordo com @Yash Você tem um único sal que usa para cada hash (não é o melhor) ou, se gerar um sal aleatório para cada hash, deve armazená-lo com o hash para usá-lo novamente mais tarde para comparação
Carson Evans

15

O erro já diz o que você deve fazer. O MD5 opera em bytes, então você deve codificar a cadeia Unicode em bytes, por exemplo, com line.encode('utf-8').


11

Por favor, dê uma olhada primeiro nessa resposta.

Agora, a mensagem de erro é clara: você só pode usar bytes, não cordas Python (o que costumava ser unicodeem Python <3), então você tem que codificar as cordas com a sua codificação preferida: utf-32, utf-16, utf-8ou até mesmo um dos restrita 8- codificações de bits (o que alguns chamam de páginas de código).

Os bytes no seu arquivo de lista de palavras estão sendo automaticamente decodificados para Unicode pelo Python 3 conforme você lê o arquivo. Eu sugiro que você faça:

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

para que os dados codificados enviados ao algoritmo MD5 sejam codificados exatamente como o arquivo subjacente.


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

6

Você pode abrir o arquivo no modo binário:

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 linha corrigiu para mim.

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

0

Se é uma string de linha única. envolva-o com b ou B. por exemplo:

variable = b"This is a variable"

ou

variable2 = B"This is also a variable"

-3

Este programa é a versão aprimorada e sem erros do cracker MD5 acima, que lê o arquivo que contém a lista de senhas com hash e verifica a palavra com hash na lista de palavras do dicionário em inglês. Espero que seja útil.

Eu baixei o dicionário de inglês no link a seguir 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()
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.