如何在Python中使用hashlib解密?

25

我知道如何加密:

encrypted = hashlib.sha256('1234').hexdigest()

但我不确定如何解密这个?

decrypted = decrypt(encrypted)

10
哈希算法并不是这样运作的。通常来说,哈希算法的整个意义在于它是无法被撤销的。哈希算法不是一种加密技术。 - BrenBarn
wikipedia 上有一篇关于哈希函数的不错文章。 - Fredrik Pihl
想一想,如果你能够“解密”一个哈希值,比如SHA256的32字节,那么你就会拥有终极压缩方法。但是当然你不能这样做,对于任何长度大于哈希值的数据,都会存在哈希碰撞,也就是不同的数据产生相同的哈希值(但是使用加密安全的哈希算法,比如SHA256,在当前或可预见的计算机上无法找到或创建碰撞)。 - hyde
1
为什么会存在碰撞,附带一个简单的例子:http://en.wikipedia.org/wiki/Pigeonhole_principle - Anil Vaitla
从sha1中获取原始字符串的唯一方法是暴力破解。对于任何哈希函数,都没有解密功能。这就是哈希的全部意义。然而,可以通过暴力破解sha1(小字符串)来获取原始字符串。 - Yogeesh Seralathan
关于哈希函数不属于“加密”的问题,有进一步的解释 - 一个哈希值可以由许多不同的输入文本产生 - 对于任意长度的输入数据,任何哈希值都可以由无限数量的输入(长度可能不同)产生! - MikeW
7个回答

34

像sha256这样的哈希函数的作用是它应该是单向函数(尽管真正的单向函数的存在仍然是一个未解决的问题,参见http://en.wikipedia.org/wiki/One-way_function)。

注意:http://en.wikipedia.org/wiki/Cryptographic_hash_function

理想的密码哈希函数具有四个主要属性:

    1. 对于任何给定的消息,都很容易计算出哈希值
    1. 生成具有给定哈希值的消息是不可行的
    1. 修改消息而不更改哈希值是不可行的
    1. 找到两个具有相同哈希值但内容不同的消息是不可行的。

如果您能够反转它,则会违反规则2。这些规则允许一方告诉另一方他们拥有某些信息(例如密码),而不泄露该信息。例如,请参阅维基百科:http://en.wikipedia.org/wiki/Cryptographic_hash_function#Illustration

如果您需要可逆性,请参见Simple way to encode a string according to a password?,您可以使用类似维吉尼亚密码这样的较弱算法,但也有一个使用PyCrypto的示例。

from Crypto.Cipher import AES
import base64

cipher = AES.new(secret_key,AES.MODE_ECB) # never use ECB in strong systems obviously
encoded = base64.b64encode(cipher.encrypt(msg_text))
# ...
decoded = cipher.decrypt(baes64.b64decode(msg_text))

如果您需要一个可逆的哈希函数,请参见Reversible hash function?


加密函数显示“ValueError: 输入字符串的长度必须是16的倍数” - Evren Yurtesen

7
短答案是你不能“解密”哈希值;它是一个单向函数。加密和哈希之间有很大的区别。
哈希
参见http://en.wikipedia.org/wiki/Cryptographic_hash_function 注意:某些哈希算法可以被“破解”,但这不是解密。您将在链接中找到更多信息,以及其他由Python支持的算法。
加密
http://en.wikipedia.org/wiki/Encryption 例子
哈希的一个有用的例子是在数据库中存储密码,而加密的一个有用的例子是向在线商店发送您的银行详细信息以购买东西。

6

这是一个有效的问题,可能没有正确表达。

楼主,我认为你想做的是检查一个已经哈希过的值和一个未经哈希的值是否匹配?

hashed = hashlib.sha256('1234').hexdigest()
hashedstring = '1234' + ',' + hashed

现在需要检查 hashed 是否等于原始值。因此,解析逗号前后的部分。对 1234 进行哈希,然后将其与哈希值进行比较。

def check_secure_val(h):
    commapos = h.find(",")
    val = h[0:commapos]
    hashval = h[commapos+1:-1]
    rehashval = hash_str(val)
    if rehashval == hashval:
        return val

其中输入的 h 是一个格式为 "val,(HASHEDSTRING)" 的字符串,而 hash_str 是一个哈希函数。

3

不太准确的比喻:加密就像某人戴上伪装...获取哈希值就像获取他们的指纹!

你可以通过去除/反转伪装来找回“原始”人,但是你无法从一组指纹中做到这一点!


14
非常糟糕的类比。 - DollarAkshay
是的,@AkshayLAradhya所说的并不是非常精确。然而,考虑到问题所涉及的知识状态,它传达了期望和现实之间的差距程度。它并不旨在解释哈希或加密 - 只是它们之间差异的程度。 因此,这取决于您的期望; 我在我的教学标准上相当严格,但我认为我的“答案”会传达这个问题。 - MikeW

3
哈希是使用单向函数计算的,即对于特定的输入,它将给出相同的输出,但由于它只是一个单向函数,无论你做什么,都不能解密它。可以尝试通过暴力破解来解密它,即计算字典中单词的哈希值并将其与要解密的哈希值进行比较。
为了节省计算字典单词哈希值的时间,在线上有彩虹表可用,其中包含带有单词的哈希值。
阅读:http://en.wikipedia.org/wiki/Rainbow_table 您还可以使用在线服务来进行哈希的暴力破解。有很多这样的服务可用,如果要解密的单词属于字典,则效果很好。

0

我认为你不能解密它,但你可以尝试使用猜测密码的范围,例如在for循环中将所有密码"{password: hashed password}"放入,然后检查哈希值,也许你会得到正确的密码。

假设你想要破解一个CSV文件中的密码,该密码位于0000-9999之间。

输入的CSV文件应该像这样:

名称,哈希密码

首先,我们需要导入csv和hashlib。

import hashlib
import csv

现在让我们编写一个函数,它以哈希化的 CSV 文件和输出 CSV 文件作为参数。我们将创建一个空字符串和一个空字典。
def decryptor(input_file_name,output_file_name):
    # makes hashes
    clear_text = ""
    mydict = {}

现在让我们在0到9999的范围内创建一个for循环,并对该范围内的每个数字进行加密。
    for i in range(0, 10000):
        i = str(i).encode('utf-8') 
        encrypted = hashlib.sha256(i).hexdigest()
        mydict[i] = encrypted

现在我们将把它们写入CSV文件中

    with open(input_file_name, 'r') as hash_file:
        # read's from csv file
        reader = csv.reader(hash_file)
        hash_dict = {}
        # reades every line of csv file
        for row in reader:
                hash_dict[row[0]] = row[1]

现在我们只需要将要解密的哈希值与我们已有的哈希值比对,就可以得到未加密的密码

    check_hash = []
    for i in list(mydict):
        text = "%s" % (mydict[i])
        check_hash.append(mydict[i])
    for i in list(hash_dict):
        if hash_dict[i] in check_hash:
            hashes = list(mydict.keys())[list(mydict.values()).index(hash_dict[i])]
            names = list(hash_dict.keys())[list(hash_dict.values()).index(hash_dict[i])],
            text = "%s,%s\n" % (names[0], hashes.decode('utf-8'))
            clear_text += text

现在我们将输出写入输出CSV文件。
    with open(output_file_name, 'w') as passwords:
        passwords.write(clear_text)

然后我们只需调用该函数

decryptor(<INPUT CSV>, <OUTPUT CSV NAME>)

这是我的想法,当然你不能直接使用,它只是一个想法,希望能对你有所帮助 :)


请添加详细回答和简单代码,使您的回答更有用。 - xitas
1
由于您目前的回答写得不够清晰,请[编辑]以添加更多细节,以帮助其他人理解它如何回答所提出的问题。您可以在帮助中心中找到有关编写良好答案的更多信息。 - Community
嘿,抱歉我没有嵌入任何代码,我现在会立即添加。 - Bourn Again

0

这可能有帮助吗?

import hashlib

l = ["riyad", "onni", "arman"]

def check_user(h):
    for i in l:
        if h == hashlib.md5(i.encode('utf-8')).hexdigest():
            return i


print(check_user(hashlib.md5(l[2].encode('utf-8')).hexdigest()))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接