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()
JohnnyFromBF
fonte
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')
cwallenpoole
fonte
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'
Jay Patel
fonte
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()
Khắc Nghĩa Từ
fonte
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').

Cat Plus Plus
fonte
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.

tzot
fonte
10
import hashlib
string_to_hash = '123'
hash_object = hashlib.sha256(str(string_to_hash).encode('utf-8'))
print('Hash', hash_object.hexdigest())
Sabyasachi
fonte
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
jfs
fonte
6

codificar esta linha corrigiu para mim.

m.update(line.encode('utf-8'))
Mike Cash
fonte
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"
SBimochan
fonte
-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()
udz
fonte