2013-09-10 3 views
0

Используйте тот же метод, приведенный ниже, для шифрования одного и того же открытого текста дважды, но зашифрованный текст не является таким же после шифрования. Почему?Шифрование не такое же, используя тот же метод для шифрования одного и того же открытого текста.

Я хочу зашифровать свой пароль при сохранении информации о пользователе в базе данных и использовать метод шифрования ниже. Но я хочу закончить функцию редактирования пользователя после ввода старого пароля и нового пароля, узнать пользователя в соответствии с выбранный идентификатор пользователя и зашифровать старый пароль, попробуйте проверить старый пароль, который соответствует паролю, хранящемуся в базе данных. Но они никогда не совпадали, даже если я ввожу правильный пароль. Так есть ли способ зашифровать пароль и подтвердить, одинаковы после использования того же метода для шифрования пароля.

//encrypt the plainText 
    public static string Encrypt(string plainText) 
    { 
     if (plainText == null || plainText == "") 
      throw new ArgumentNullException("plainText"); 
     var temp = Encoding.UTF8.GetBytes(plainText); 

     byte[] encrypted = ProtectedData.Protect(temp, null, DataProtectionScope.CurrentUser); 
     return Convert.ToBase64String(encrypted); 
    } 

ответ

3

Основываясь на MSDN documentation of the ProtectedData class, похоже, что он выполняет 2-полосная шифрование с использованием машинно или конкретного пользователя ключа. Это означает, что если машина или пользователь, который активно проверяет ключ, отличается от машины, которая первоначально зашифровала его, вы получите результаты мусора. Если вы хотите только проверить правильность пароля, я бы предложил алгоритм хэширования с односторонним доступом вместо двухстороннего шифрования, поддерживающего расшифровку. Другие сообщения в StackOverflow говорят об использовании безопасных алгоритмов хеширования (What is the most secure hashing algorithm in the .NET framework?).

Редактировать: Я не тестировал этот код на разных системах под разными пользователями, но я ожидаю, что он будет работать более универсально, потому что я не ожидаю, что он основан на машине или пользовательском ключе.

System.Security.Cryptography.SHA256Managed sha = new System.Security.Cryptography.SHA256Managed(); 
byte[] hashed = sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes(args[0])); 
Console.WriteLine("Hash of {0}={1}", args[0], Convert.ToBase64String(hashed)); 

Edit 2: Я хотел бы также добавить, что мое понимание криптографии также предполагает, что вы должны, вероятно, включать некоторые «соль» в вашем значении хэшированном. Другими словами, добавьте что-то (например, имя пользователя) в конец строки пароля перед его хэшированием (как при вводе, так и при проверке), чтобы пользователи с одним и тем же паролем не имели одинаковое значение хэша, например ,

+0

Я думаю, что он действительно хочет хэш (он сравнивает две зашифрованные строки) ... То, что вы говорите, правильно, и мой ответ тоже прав ... Но у меня есть ощущение, что первый человек должен опубликовать метод хэширования для парня получит очки;) – Faraday

+1

Один раунд SHA256 действительно недостаточен, он лучше, чем один раунд SHA1, но не намного лучше. Библиотека, подобная [BCrypt] (https://bcrypt.codeplex.com/), является гораздо более гибким решением для хэширования паролей. – Syon

+0

Да, хотя я умеренно знаком с тем, как работает шифрование, я должен уточнить, что я не эксперт по безопасности, поэтому, если степень безопасности важна для вас, я бы рекомендовал вам изучить алгоритм, который вы используете вместо моего SHA256 пример. Код, который я предоставляю, является лишь примером использования одностороннего хэширования и не обязательно представления о том, какая форма хеширования наиболее безопасна или целесообразна. (+1 на комментарий осторожности.) – BlueMonkMN

0

Вот что-то, что я бросил в консольное приложение. Шифры не будут соответствовать, но, как вы можете видеть, вы можете расшифровать их просто отлично :)

class Program 
{ 
    private static string salt = "My Salt Brings All The Boys To The Yard... Wait A Second....."; 
    static void Main(string[] args) 
    { 
     for (int i = 0; 0 < 20; i++) 
     { 
      string password = "Guess my password!"; 

      string cipher = Encrypt(password, salt); 

      string decipher = Decrypt(cipher, salt); 

      Console.WriteLine(decipher); 
      Thread.Sleep(500); 
     } 
     Console.ReadKey(); 

    } 

    static public string Encrypt(string password, string salt) 
    { 
     byte[] passwordBytes = Encoding.Unicode.GetBytes(password); 
     byte[] saltBytes = Encoding.Unicode.GetBytes(salt); 

     byte[] cipherBytes = ProtectedData.Protect(passwordBytes, saltBytes, DataProtectionScope.CurrentUser); 

     return Convert.ToBase64String(cipherBytes); 
    } 

    static public string Decrypt(string cipher, string salt) 
    { 
     byte[] cipherBytes = Convert.FromBase64String(cipher); 
     byte[] saltBytes = Encoding.Unicode.GetBytes(salt); 

     byte[] passwordBytes = ProtectedData.Unprotect(cipherBytes, saltBytes, DataProtectionScope.CurrentUser); 

     return Encoding.Unicode.GetString(passwordBytes); 
    } 
} 
1

Некоторой хаотичность в выходном фактически feature for encryption.

Вы получаете два варианта:

  • Если вы когда-нибудь понадобитесь, чтобы восстановить пароль от зашифрованного вида как часть ваших требований, использовать шифрование, как и вы, но расшифровать результат, прежде чем сделать сравнение между ожидаемым и введите пароль.

  • Если вам действительно не нужно восстанавливать пароль, используйте вместо этого хэш-алгоритм (с подходящей солью). Вы сможете сравнить два значения хэширования.

Смежные вопросы