4

我有一个 PHP Web 服务,我发现它正在向我的 C# 传递一个 SHA-1 encrupted 值。传递给我的示例数据是“8cb2237d0679ca88db6464eac60da96345513964”,我知道它可以转换为“12345”。

如何使用类似于以下的代码将哈希值转换回“12345”

public static string HashCode(string str)
{
string rethash = "";
try
{

      System.Security.Cryptography.SHA1 hash = System.Security.Cryptography.SHA1.Create();
       System.Text.ASCIIEncoding encoder = new System.Text.ASCIIEncoding();
       byte[] combined = encoder.GetBytes(str);
       hash.ComputeHash(combined);
       rethash = Convert.ToBase64String(hash.Hash);
}
catch (Exception ex)
{
       string strerr = "Error in HashCode : " + ex.Message;
}
return rethash;
}
  • 编辑 *

这是一些 RUBY 代码,它也适用于“8cb2237d0679ca88db6464eac60da96345513964”和“12345”

require "digest/sha1"
class User
  attr_accessor :password
  def initialize(password)
    @password = hash_password(password)
  end
  def hash_password(password)
    Digest::SHA1.hexdigest(password)
  end
  def valid_password?(password)
    @password == hash_password(password)
  end
end
u = User.new("12345")
p u.password # => "8cb2237d0679ca88db6464eac60da96345513964"
p u.valid_password?("not valid") # => false
p u.valid_password?("12345") # => true
4

6 回答 6

6

您无法解密 SHA1 哈希,因为它是单向哈希。

另一个散列方式的例子是 MD5

于 2013-01-31T16:31:47.117 回答
4

12345 将始终以 8cb2237d0679ca88db6464eac60da96345513964 的形式出现,并带有直接哈希。

这意味着,如果您为每个可能的结果创建了一个数据库,理论上您可以查找结果并从中查看 sha1 函数的原始输入是什么。

这是一个安全问题,可能存在诸如字典攻击和彩虹表之类的问题 ( http://en.wikipedia.org/wiki/Rainbow_table )。

为了解决这个问题,你永远不应该使用未加盐的哈希。即,您始终使用您已知的值自定义您的哈希值。

例如 sha1("12345" + "mySalt")。

现在您的哈希值很容易计算出来,但与世界上所有使用过 sha1 的人不同。

从技术上讲,你也不应该重复使用相同的盐两次,但这是一个更复杂的概念。

编辑:正如 owlstead 在下面指出的那样,应该使用 PBKDF2 和随机盐,而不是静态盐和散列。安全性要好得多。

于 2013-01-31T17:04:52.603 回答
4

您发布的 ruby​​ 代码似乎没有反转哈希。

它似乎在做的是:

获取密码文本,对其进行哈希处理并存储。

稍后,当它想检查“用户”是否再次输入了相同的密码时,它会从用户那里获取密码文本,对其进行哈希处理,并将哈希值与存储的哈希值进行比较。

这是存储和检查密码的常用方法。不是“去散列”存储的值进行比较,而是散列新值并比较两个散列值。

于 2013-01-31T17:05:02.430 回答
2

您正在寻找的代码是这个

SHA1 sha = new SHA1CryptoServiceProvider();
ASCIIEncoding encoder = new ASCIIEncoding(); 
byte[] combined = encoder.GetBytes(pin);
string hash = BitConverter.ToString(sha.ComputeHash(combined)).Replace("-", "");

其中pin是未散列的值,而hash是您要比较的值

于 2013-03-24T19:22:51.597 回答
1

散列不是可逆操作,如加密。

于 2013-01-31T16:32:58.470 回答
1

散列不是加密。散列是一种方法,在大多数情况下用于验证数据完整性。

于 2013-01-31T16:33:28.920 回答