在C#中反转MD5哈希算法

8

可能是重复问题:
如何反向解析MD5哈希值

给定C#中的这个方法:

public string CalculateFileHash(string filePaths) {
    var csp = new MD5CryptoServiceProvider();
    var pathBytes = csp.ComputeHash(Encoding.UTF8.GetBytes(filePaths));
    return BitConverter.ToUInt64(pathBytes, 0).ToString();
}

如何使用“DecodeFileHash”方法来反转此过程?
var fileQuery = "fileone.css,filetwo.css,file3.css";
var hashedQuery = CalculateFileHash(fileQuery); // e.g. "23948759234"
var decodedQuery = DecodeFileHash(hashedQuery); // "fileone.css,filetwo.css,file3.css"

最终decodedQuery == fileQuery,这是否可能?如果不可能,是否有任何方法可以生成一个易于解码的哈希值?

编辑:为了明确起见,我只想压缩变量“fileQuery”,并解压缩fileQuery以确定它最初是什么。有没有解决这个问题的建议,因为哈希/解码已经不可行了?

再次编辑:仅进行base64编码/解码似乎是最佳解决方案。

public string EncodeTo64(string toEncode) {
    var toEncodeAsBytes = Encoding.ASCII.GetBytes(toEncode);
    var returnValue = System.Convert.ToBase64String(toEncodeAsBytes);
    return returnValue;
}

public string DecodeFrom64(string encodedData) {
    var encodedDataAsBytes  = System.Convert.FromBase64String(encodedData);
    var returnValue = Encoding.ASCII.GetString(encodedDataAsBytes);
    return returnValue;
}

你为什么想要反转哈希呢?你想要实现什么目标? - Thomas
我正在尝试构建一个文件名链,对实际文件名进行压缩,但对它们进行解码以找出包含在连接文件中的文件名。 - tester
听起来你正在尝试压缩文件。我已经发布了一个可能看起来像什么的例子。 - Thomas
6个回答

15

不可能。按照定义和设计,哈希值无法还原为纯文本或其原始输入。


听起来你实际上是在尝试压缩文件。如果是这种情况,这里有一种使用GZip进行简单压缩的方法:

public static byte[] Compress( byte[] data )
{
    var output = new MemoryStream();
    using ( var gzip = new GZipStream( output, CompressionMode.Compress, true ) )
    {
        gzip.Write( data, 0, data.Length );
        gzip.Close();
    }
    return output.ToArray();
}

2
虽然你可能会很幸运地能够反转短字符串的MD5和类似的内容(例如MD5(test) <=> 098f6bcd4621d373cade4e832627b4f6),但你永远无法确定你找到的字符串是原始字符串还是碰撞。另请参见http://www.mscs.dal.ca/~selinger/md5collision/,其中有一些有趣的碰撞示例。 - schnaader
2
@tester - 顺便说一下,那个网站没有考虑盐值。也就是说,如果在哈希之前添加了盐值,则该网站将无法帮助您(这也是为什么您应该使用盐值的原因)。 - Thomas
10
如果你能够反向一个哈希函数,那么你将会拥有最强大的压缩算法。不论你使用 MD5 哈希什么内容,结果都是 128 位二进制数。如果你能够反向操作,就可以从这个 128 位的哈希值中恢复出你的 600MB 视频文件! - Timothy Strimple
1
@tester:该网站仅对使用md5encrypter.com创建MD5的字符串进行反向操作。为了证明这一点,请使用其他工具为某个随机文本字符串创建一个MD5。将该MD5输入到md5decrypter.com中,它会显示未知。然后使用md5encrypter.com创建MD5,并将该MD5再次输入到md5decrypter.com中。它会显示已知。 - CanSpice
1
@tester - 你可以同时用那个解决方案。 - Thomas
显示剩余7条评论

6

哈希是从原始信息派生出来的,但不包含原始信息。如果您需要一个隐藏原始信息但可被还原为原始值的短值,您的选择相当有限:

  • 压缩原始信息。如果你需要一个字符串,则原始信息必须相当大,以便压缩后的 base-64 编码版本不会比原始数据更大。
  • 加密原始信息 - 这比仅压缩它更安全,并且可以与压缩组合使用,但也可能比原始信息更大。
  • 将原始信息存储在某个地方并返回查找键。

1
通常从原始信息中派生出来的?如果不是从原始信息中派生出来的,那么是从哪里派生出来的?加盐哈希仍然是从原始信息派生而来...否则这有什么意义呢? - Matthew
1
好的,好的,你赢了一个吹毛求疵的点。 - Joel Mueller

4
您想要做的是加密和解密,而不是哈希和反哈希,正如@Thomas所指出的那样,这是不可能的。哈希通常会被使用彩虹表或其他数据集打败,其中包括某些生成相同哈希的东西...不能保证是输入值,只是在哈希算法中产生相同输出的某些值。
Jeff Atwood在此处提供了一些很好的理解加密的代码:
http://www.codeproject.com/KB/security/SimpleEncryption.aspx 如果这对您有用。

是的,我想我当时考虑使用 MD5 进行加密。有什么简单的加密和解密方法吗? - tester
@tester,我发布的Jeff Atwood的代码是一个杰出的跳板。 - Matthew

4

按照定义,密码哈希在典型的计算能力下是不可逆的。甚至可能找不到与原始输入具有相同哈希值的任何输入。

如果存在超过2^n个不同输入,即哈希值的比特长度n(md5为128),则数学上不可能恢复原始输入。可以查阅鸽巢原理。

哈希函数不是无损压缩函数。


4

如果你想要获取数据,你需要的是压缩而不是哈希。


如何编写一个解决我的问题的压缩方法? - tester
我不确定。通用压缩算法并不能很好地处理短字符串——“压缩”版本可能比原始版本更长,并且很可能包含文件路径中不允许的字符。那么另一种方法呢:为什么不只是在连接的数据前面添加原始文件路径呢? - Rob Agar

3
一个密码哈希函数,例如MD5,被设计成为单向函数,也就是说,从给定哈希计算出源数据在计算上是不可行的。然而,由于已经发现了弱点,MD5已经被认为不安全了一段时间: MD5安全性维基百科 MD5被认为是有害的 MD5的另一个弱点是,由于其相对较小的大小,已经发布了大量的彩虹表,让你可以查找给定的MD5哈希以获取与指定哈希值冲突的源输入。 彩虹表

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