为什么这个unhash函数不能反转这个哈希?

时间:2017-05-26 09:23:44

标签: actionscript-3 hash actionscript cryptography bit-manipulation

我写了一个用于密码和密钥生成的散列函数,但很快意识到能够反转散列是非常有价值的,所以我写了一个相反的函数,但是,它起作用了。我不知道为什么这个DOESNT会工作。

function hash64(n:uint):uint
{
    n = (~n) + (n << 21);
    n = n ^ (n >> 24);
    n = (n + (n << 3)) + (n << 8);
    n = n ^(n >> 14);
    n = (n + (n << 2)) + (n << 4);
    n = n ^ (n >> 28);
    n = n + (n << 31);
    return n;
}

function unhash64(n:uint):uint
{
    n = (~n) - (n >> 21);
    n = n ^ (n << 24);
    n = (n - (n >> 3)) - (n >> 8);
    n = n ^ (n << 14);
    n = (n - (n >> 2)) - (n >> 4);
    n = n ^ (n << 28);
    n = n - (n >> 31);
    return n;
}

喂1000时的输出:

Hashed from 1000:           1221775646
Unhash output:              1963490760

2 个答案:

答案 0 :(得分:5)

第一个明显的问题是它没有及时镜像。 有时有效(如果操作顺序首先不重要),但通常y = f(g(x))的倒数为x = g⁻¹(f⁻¹(y))。 f最后应用,因此必须首先撤消。比较一下:如果你先穿上袜子然后穿上你的鞋子,你应该先脱掉鞋子然后脱掉袜子。

此外,许多反转开始时都是错误的。例如,相反的 m = n ^ (n >> 24)n = m ^ (m >> 24),而m = (n + (n << 2)) + (n << 4)的倒数为n = m * 0x3cf3cf3d(它是modular multiplicative inverse)。它并不像换班方向那么简单。

未经测试,但这些都是正确顺序的反转:

n = n * 0x80000001;
n = n ^ (n >> 28);
n = n * 0x3cf3cf3d;
n = n ^ (n >> 14) ^ (n >> 28);
n = n * 0x1c03dd39;
n = n ^ (n >> 24);
n = (n + 1) * 0xffdfffff;

答案 1 :(得分:1)

哈希不可逆转。如果您想要隐藏原始输入的可逆功能,请使用加密。只要您拥有正确的密钥,加密就是可逆的。

已经有众所周知的密码和密钥生成技术。如果您尝试设计自己的版本,那么它们将是不安全的。没关系,你要做的就是隐藏你孩子兄弟的东西。如果您在商业区工作,那么您可能会被起诉,因此请使用所有标准的现有安全方法。您可能想要研究关键衍生函数,如PBKDF2或argon2。