是否可以解密SHA1

use*_*407 13 security sha1 sha spring-security

是否可以解密(保留实际字符串)使用SHA1算法保存在db中的密码.

示例:如果密码是"password",它是存储在DB如"sha1$4fb4c$2bc693f8a86e2d87f757c382a32e3d50fc945b24",是任何机会保持相同的"password"(string)"sha1$4fb4c$2bc693f8a86e2d87f757c382a32e3d50fc945b24"

pro*_*der 24

SHA1 是一个加密哈希函数,所以设计的目的是避免你想要做的事情.

但是,打破SHA1哈希在技术上是可行的.你可以通过猜测什么是哈希来做到这一点.这种蛮力方法当然效率不高,但这几乎是唯一的方法.

所以回答你的问题:是的,这是可能的,但你需要很大的计算能力.一些研究人员估计它的成本为7万美元至12万美元.

就我们今天所知,除了猜测哈希输入之外别无他法.这是因为诸如mod消除输入信息之类的操作.假设你计算mod 5得到你0.输入是什么?是吗0,5还是500?你知道,在这种情况下,你真的不能"回去".

  • 你提出了一个很好的观点.但是有许多网站为sha1提供解密. (3认同)
  • 好点子.因此,如果您想要进行反向哈希查找,并非一切都会丢失:)但这是一个不同的原则.该服务获取一些文件并计算哈希并将其存储在数据库中.所以你可以进行反向查找.但是,这些服务不会解密SHA-1哈希.因此,如果输入该数据库不知道的哈希值,则不会得到结果.在我看来,问题的目的是要求一种算法来有效地解密任意哈希.这是不可能的(据我们所知). (3认同)

Ren*_*ink 6

SHA1是一种单向哈希。因此,您无法真正还原它。

这就是为什么应用程序使用它来存储密码的哈希而不是密码本身的原因。

像每个散列函数一样,SHA-1将较大的输入集(键)映射到较小的目标集(散列值)。因此可能发生碰撞。这意味着输入集的两个值映射到相同的哈希值。

显然,当目标集变得越来越小时,碰撞概率会增加。但是反之亦然,这也意味着当目标集变大并且SHA-1的目标集为160位时,冲突概率会降低。

Jeff Preshing撰写了有关Hash Collision Probabilities的很好的博客,可以帮助您决定使用哪种哈希算法。谢谢杰夫。

在他的博客中,他显示了一个表,该表告诉我们给定输入集发生冲突的可能性。

哈希冲突概率表

如您所见,如果您有77163个输入值,则32位哈希的概率为1比2。

一个简单的java程序将向我们展示他的表显示的内容:

public class Main {

    public static void main(String[] args) {
        char[] inputValue = new char[10];

        Map<Integer, String> hashValues = new HashMap<Integer, String>();

        int collisionCount = 0;

        for (int i = 0; i < 77163; i++) {
            String asString = nextValue(inputValue);
            int hashCode = asString.hashCode();
            String collisionString = hashValues.put(hashCode, asString);
            if (collisionString != null) {
                collisionCount++;
                System.out.println("Collision: " + asString + " <-> " + collisionString);
            }
        }

        System.out.println("Collision count: " + collisionCount);
    }

    private static String nextValue(char[] inputValue) {
        nextValue(inputValue, 0);

        int endIndex = 0;
        for (int i = 0; i < inputValue.length; i++) {
            if (inputValue[i] == 0) {
                endIndex = i;
                break;
            }
        }

        return new String(inputValue, 0, endIndex);
    }

    private static void nextValue(char[] inputValue, int index) {
        boolean increaseNextIndex = inputValue[index] == 'z';

        if (inputValue[index] == 0 || increaseNextIndex) {
            inputValue[index] = 'A';
        } else {
            inputValue[index] += 1;
        }

        if (increaseNextIndex) {
            nextValue(inputValue, index + 1);
        }

    }

}
Run Code Online (Sandbox Code Playgroud)

我的输出以以下结尾:

Collision: RvV <-> SWV
Collision: SvV <-> TWV
Collision: TvV <-> UWV
Collision: UvV <-> VWV
Collision: VvV <-> WWV
Collision: WvV <-> XWV
Collision count: 35135
Run Code Online (Sandbox Code Playgroud)

它产生了35135个碰撞,大约是77163的一半。如果我使用30084个输入值运行该程序,则碰撞计数为13606。这不是十分之一,但这只是一个概率,示例程序并不完美,因为它仅使用A和之间的ascii字符z

让我们来看看上一次报告的碰撞并检查

System.out.println("VvV".hashCode());
System.out.println("WWV".hashCode());
Run Code Online (Sandbox Code Playgroud)

我的输出是

86390
86390
Run Code Online (Sandbox Code Playgroud)

结论:

如果您具有SHA-1值,并且想要取回输入值,则可以尝试进行蛮力攻击。这意味着您必须生成所有可能的输入值,对它们进行哈希处理,然后将其与SHA-1进行比较。但这将消耗大量时间和计算能力。有人创造了所谓的彩虹桌某些输入集。但是这些仅对于一些小的输入集才存在。

请记住,许多输入值映射到单个目标哈希值。因此,即使您知道所有映射(这是不可能的,因为输入集是无界的),您仍然无法说出它是哪个输入值。


Jon*_*oni 5

由于SHA-1将多个字节序列映射到一个,因此您无法"解密"散列,但理论上您可以找到冲突:具有相同散列的字符串.

似乎打破一个哈希值目前的计算机时间大约需要270万美元,所以你的努力可能会更好地花在其他地方.

  • 现在大约75K-120K美元,这取决于所涉及数据的重要性.:-) (5认同)