如何在Java中解密SHA1加密的字符串

9

在Java中,是否有可能解密之前使用SHA-1算法加密的某些字符串?


2
SHA-1是一种哈希算法,而不是加密算法。如果你试图从它的SHA-1哈希中提取一个字符串,祝你好运。这被称为预像攻击。 - Mysticial
1
这是“可能的”,但需要计算资源和时间,因为sha1加密数据一旦加密就不应该被解密。 - jsvk
我认为问题应该是解密sha1有多大的计算强度。这与Java有什么关系呢?如果你有一个好的算法,你可以使用任何语言来编写它。 - Ustaman Sangat
3个回答

12

SHA1是一种密码散列函数, 它的主要作用是无法撤销。如果可以反向计算哈希值(查找给定哈希值对应的输入),那么它就没有用了。如果需要加密和解密某些内容,应该使用像AES或者RSA这样的加密函数

然而,对于非常简单的输入,有可能通过猜测输入并检查哈希值是否相同来破解哈希函数

示例Python代码:

def crack_hash(hash_to_crack, hash_function, list_of_guesses):
    # Try to hash everything in our guess list
    for guess in list_of_guesses:
        new_hash = hash_function(guess)
        # if the hashes match, we found it
        if new_hash == hash_to_crack:
            return guess
    # If none of them match, give up
    return None

当然,如果您真的想高效地破解哈希值,使用像John the RipperHashcat这样的软件可能是最好的选择。请注意,这通常适用于密码,因为它们简短且容易猜测,但随着输入量的增加,难度呈指数级增加。您可以在几分钟内破解每个具有6个字符输入的SHA-1哈希值,而破解具有16个字符的哈希值平均需要数万亿年。

这种方法需要大量的空间和时间来处理一个相当大小的列表。更实用的替代方案是利用彩虹表来进行时间-内存权衡。但是,这种方法对于加盐哈希是无用的。 - jsvk
@jsvk - 我并不是在说这是一个好主意。事实上,我希望这个例子能够说明,除非你有一个很好的猜测,否则这是毫无意义的。它可以被改进,但现实情况是,没有人使用自己编写的密码破解程序 -- 尤其不是用 Python 编写的 ;) - Brendan Long

2
不,这是不可能的,因为SHA-1是一种哈希函数——它是单向的。如果你想加密和解密字符串,那么你需要使用一些加密算法来生成加密数据的密钥。然后你可以加密数据并在成功解密后进行解密。例如AES。你可以从这里了解AES。

2
简短回答:这是不可能的。
因为SHA-1是一个密码散列函数,根据鸽笼原理,它在数学上是不可能被反转的。只有2的160次方个可能的SHA-1哈希值。由于可能的输入字符串数量是无限的,必然会出现冲突(多个输入映射到相同的哈希值)。一般来说,你无法知道哪个字符串是原始输入。
然而,实际的字符串并非完全任意。如果你知道一些关于输入字符串的信息(例如,它少于5个字符),则很有可能该输入是唯一的。不幸的是,像SHA-1这样的哈希函数是故意计算难以反转的。(虽然有关于SHA-1的理论攻击,但目前没有任何攻击被认为是可行的。)
因此,如果你需要恢复哈希数据,你必须使用暴力破解:尝试对长度小于n的每个字符串进行SHA-1哈希,并查看哈希是否匹配。但是长度不超过n的字符串数量呈指数增长,因此这很快变得不可行。
有一种可能的方法可以在宇宙终结之前恢复哈希数据。你唯一的希望是使用更复杂的方法,例如彩虹表。这只有在您知道原始字符串非常短(少于15个字符)时才有效。即使对于短字符串,预先计算表格也需要很长时间(和大量的磁盘空间)。

请更新:这是完全可能的,我只需要算法。sha1-decrypter 是一个页面链接,您可以在该页面找到在线解密工具。 - Fr_nkenstien
2
@VineetVerma:那不是解密器,而是反向查找。它使用的代码实质上是 Map<SHA1, byte[]> lookup = new HashMap<SHA1, byte[]>(); /*添加一些常见输入*/; return lookup.get(sha1sum);。它只能在他们恰好将你要查找的输入添加到映射中时才能工作。 - Mechanical snail

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