Расшифровать значение SHA1 с помощью C#

У меня есть веб-сервис PHP, который я обнаружил, передает 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

6 ответов

Вы не можете расшифровать хеш SHA1, потому что это односторонний хеш.

Другой пример одностороннего хеширования - MD5

12345 всегда будет выглядеть как 8cb2237d0679ca88db6464eac60da96345513964 с прямым хешем.

Это означает, что если вы создали базу данных для каждого возможного результата, вы теоретически могли бы найти результат, и из этого посмотреть, каков был исходный ввод для функции sha1.

Это проблема безопасности, при которой возможны такие проблемы, как атаки по словарю и таблицы Rainbow ( http://en.wikipedia.org/wiki/Rainbow_table).

Чтобы обойти это, вы никогда не должны использовать несоленый хеш. т.е. вы всегда настраиваете свой хеш, используя известное вам значение.

Например, sha1("12345" + "mySalt").

Теперь ваш хеш легко вычислить, но он не такой, как у любого другого человека в мире, который использовал sha1.

Технически говоря, вы также никогда не должны повторно использовать одну и ту же соль дважды, но это более сложная концепция.

РЕДАКТИРОВАТЬ: Как указывает Owlstead ниже, следует использовать PBKDF2 и случайную соль, а не статическую и хеш. Гораздо лучше для безопасности.

Размещенный вами рубиновый код не меняет хеш.

То, что, кажется, делает это:

Получите текст пароля, хэшируйте его и сохраните.

Позже, когда он хочет проверить, что "пользователь" снова ввел тот же пароль, он получает текст пароля от пользователя, хэширует его и сравнивает значение хеш-функции с сохраненным хеш-значением.

Это распространенный способ хранения и проверки паролей. Вместо того, чтобы "отключать" сохраненное значение для сравнения, вы хэшируете новое значение и сравниваете два значения хеша.

Хеширование не является обратимой операцией, как шифрование.

Код, который вы ищете, это

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

Где pin - это значение без хэша, а hash - это значение, которое вы хотите сравнить

Хеширование не является шифрованием. Хеширование является одним из способов и используется в большинстве случаев для проверки целостности данных.

Другие вопросы по тегам