我有一个PHP Web服务,我发现它正在传递我的C#SHA-1入侵值。传递给我的样本数据是“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
答案 0 :(得分:5)
您无法解密SHA1哈希,因为它是单向哈希。
单向散列的另一个例子是MD5
答案 1 :(得分:4)
12345将始终以8cb2237d0679ca88db6464eac60da96345513964的形式显示为直接哈希。
这意味着如果您创建了每个可能结果的数据库,理论上您可以查找结果,并从中查看sha1函数的原始输入是什么。
这是一个安全问题,可能会出现字典攻击和彩虹表等问题(http://en.wikipedia.org/wiki/Rainbow_table)。
要解决这个问题,你绝不应该使用未加盐的哈希值。即,您始终使用您已知的值自定义哈希值。
例如sha1(“12345”+“mySalt”)。
现在你的哈希很容易找到,但与使用sha1的世界上所有其他人不一样。
从技术上讲,你也不应该再使用相同的盐两次,但这是一个更复杂的概念。
编辑:正如owlstead在下面指出的那样,应该使用PBKDF2和随机盐,而不是静态的和哈希。安全性要好得多。
答案 2 :(得分:3)
您发布的ruby代码似乎没有反转哈希值。
它似乎正在做的是:
获取密码文本,哈希并存储。
稍后,当它想要检查“用户”是否再次输入相同的密码时,它会从用户获取密码文本,对其进行哈希处理,并将哈希值与存储的哈希值进行比较。
这是存储和检查密码的常用方法。您可以散列新值并比较两个哈希值,而不是“取消”存储的值以进行比较。
答案 3 :(得分:1)
散列不是可逆操作,如加密。
答案 4 :(得分:1)
哈希不是加密。散列是一种方式,在大多数情况下用于验证数据完整性。
答案 5 :(得分:1)
您正在寻找的代码是
SHA1 sha = new SHA1CryptoServiceProvider();
ASCIIEncoding encoder = new ASCIIEncoding();
byte[] combined = encoder.GetBytes(pin);
string hash = BitConverter.ToString(sha.ComputeHash(combined)).Replace("-", "");
pin 是未散列的值,哈希是您想要比较的值