2009-11-05 5 views
21

Я хочу простое шифрование и дешифрование пароля на C#. как сохранить пароль в зашифрованном формате в базе данных и получить в качестве исходного формата путем дешифрования, любезно помогите с образцом кода.Код шифрования/дешифрования пароля в .NET

+18

Есть ли какая-либо конкретная причина, по которой вам необходимо его получить? Большую часть времени вы можете просто использовать хеш-функцию для ее сохранения. Затем, когда они вводят свой пароль, вы хешируете их запись и сравниваете. – Cogwheel

ответ

14

Здесь вы идете. Я нашел его где-то в Интернете. Хорошо работает для меня.

/// <summary> 
    /// Encrypts a given password and returns the encrypted data 
    /// as a base64 string. 
    /// </summary> 
    /// <param name="plainText">An unencrypted string that needs 
    /// to be secured.</param> 
    /// <returns>A base64 encoded string that represents the encrypted 
    /// binary data. 
    /// </returns> 
    /// <remarks>This solution is not really secure as we are 
    /// keeping strings in memory. If runtime protection is essential, 
    /// <see cref="SecureString"/> should be used.</remarks> 
    /// <exception cref="ArgumentNullException">If <paramref name="plainText"/> 
    /// is a null reference.</exception> 
    public string Encrypt(string plainText) 
    { 
     if (plainText == null) throw new ArgumentNullException("plainText"); 

     //encrypt data 
     var data = Encoding.Unicode.GetBytes(plainText); 
     byte[] encrypted = ProtectedData.Protect(data, null, Scope); 

     //return as base64 string 
     return Convert.ToBase64String(encrypted); 
    } 

    /// <summary> 
    /// Decrypts a given string. 
    /// </summary> 
    /// <param name="cipher">A base64 encoded string that was created 
    /// through the <see cref="Encrypt(string)"/> or 
    /// <see cref="Encrypt(SecureString)"/> extension methods.</param> 
    /// <returns>The decrypted string.</returns> 
    /// <remarks>Keep in mind that the decrypted string remains in memory 
    /// and makes your application vulnerable per se. If runtime protection 
    /// is essential, <see cref="SecureString"/> should be used.</remarks> 
    /// <exception cref="ArgumentNullException">If <paramref name="cipher"/> 
    /// is a null reference.</exception> 
    public string Decrypt(string cipher) 
    { 
     if (cipher == null) throw new ArgumentNullException("cipher"); 

     //parse base64 string 
     byte[] data = Convert.FromBase64String(cipher); 

     //decrypt data 
     byte[] decrypted = ProtectedData.Unprotect(data, null, Scope); 
     return Encoding.Unicode.GetString(decrypted); 
    } 
+0

хороший ответ, я не понял часть области действия метода защиты. Я google, и я нашел, что вы можете использовать DataProtection.CurrentUser. Это нормально? или это вызовет проблемы при расшифровке? можете ли вы объяснить, что вы сделали для создания своего класса. Спасибо. – euther

+6

Возможно, я ошибаюсь, но похоже, что это решение не переносится между пользователями/машинами и поэтому не подходит для хранения зашифрованных данных. Из документации: «DPAPI хранит данные ключа в профилях пользователей». Если вы используете этот метод для шифрования и хранения данных, вы не сможете извлекать и расшифровывать данные с другой машины, или не дай бог, если вы перестраиваете свой сервер. – Brett

+1

Visual Studio не распознает «область»? –

12

EDIT: это очень старый ответ. SHA1 был устаревшим в 2011 году и теперь нарушен на практике. https://shattered.io/ Используйте вместо этого более новый стандарт (например, SHA256, SHA512 и т. Д.).

Если ваш ответ на этот вопрос в моем комментарии «Нет», вот что я использую:

public static byte[] HashPassword(string password) 
    { 
     var provider = new SHA1CryptoServiceProvider(); 
     var encoding = new UnicodeEncoding(); 
     return provider.ComputeHash(encoding.GetBytes(password)); 
    } 
+2

SHA1 был скомпрометирован, как показано здесь: http://okami-infosec.blogspot.com/2007/01/hash-sha-1-compromised.html –

+0

Я не верю, что ни одна из семейств SHA-2 не была вы можете использовать один из них: http://en.wikipedia.org/wiki/SHA_hash_functions#SHA-2_family –

+0

Но это зависит от того, насколько безопасным или каким будет параноидальным. В университете я был очень параноиком. –

0

Один из самых простых методов шифрования (если вы абсолютно должны сделать один до себя, так как .NET имеет такие awesome библиотеки шифрования уже [как предоставлено Cogwheel как раз передо мной]) - это XOR значение ASCII каждого символа входной строки с известным «ключевым» значением. Функциональность XOR в C# выполняется с использованием ключа ^, который я считаю.

Затем вы можете преобразовать значения из результата XOR в ASCII Chars и сохранить их в базе данных. Это не очень безопасно, но это один из самых простых способов шифрования.

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

+0

Я знаю, да? * невинно оглядывайся * (На самом деле, я нахожусь в середине написания предложения о том, чтобы избавиться от системы, которую я унаследовал и вступил в XXI век) – Cogwheel

+5

Бог поможет нам всем :( – zebrabox

+0

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

3

Этот вопрос будет отвечать как для шифрования/дешифрования: Encrypt and decrypt a string

Вы не указали базы данных, но вы хотите, чтобы базировать-64 закодировать ее, используя Convert.toBase64String. Для примера вы можете использовать: http://www.opinionatedgeek.com/Blog/blogentry=000361/BlogEntry.aspx

Вы затем либо сохранить его в VARCHAR или CLOB, в зависимости от того, как долго ваш зашифрованное сообщение, но для пароля VARCHAR должен работать.

Приведенные выше примеры также будут охватывать дешифрование после декодирования base64

UPDATE:

В действительности вы не можете использовать кодировку base64, но я нашел, что это полезно, в случае, если я хотел напечатать или отправить его через Интернет. Если сообщение достаточно продолжительное, мне было удобно сначала сжать его, а затем зашифровать, так как сложнее использовать грубую силу, когда сообщение уже было в двоичной форме, поэтому было бы трудно сказать, когда вы успешно нарушили шифрование ,

+0

Помимо переносимости, существуют ли существенные преимущества для использования base-64 вместо двоичного (если db поддерживает его)? – Cogwheel

+0

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

+0

Хорошая точка ... Я конвертировал хэш в строку один раз во время отладки и сравнивал полученный kanji>< – Cogwheel

0

Вы можете использовать управляемую библиотеку криптографии .Net, а затем сохранить зашифрованную строку в базе данных. Когда вы хотите проверить пароль, вы можете сравнить сохраненную строку базы данных с хешированным значением пользовательского ввода. См. Здесь для получения дополнительной информации о SHA512Managed

using System.Security.Cryptography;

public static string EncryptSHA512Managed(string password) 
    { 
     UnicodeEncoding uEncode = new UnicodeEncoding(); 
     byte[] bytPassword = uEncode.GetBytes(password); 
     SHA512Managed sha = new SHA512Managed(); 
     byte[] hash = sha.ComputeHash(bytPassword); 
     return Convert.ToBase64String(hash); 
    } 
+4

1) Плохое имя метода, так как вы hash и не шифруете. 2) Не используйте быстрый хеш для хеширования паролей. Единственная итерация SHA-2 недостаточно хороша. Используйте scrypt, bcrypt или PBKDF2. Это также не ответ на вопрос, так как ОР нуждается в обратимости. – CodesInChaos

3

Я использую RC2CryptoServiceProvider.

public static string EncryptText(string openText) 
    { 
     RC2CryptoServiceProvider rc2CSP = new RC2CryptoServiceProvider(); 
     ICryptoTransform encryptor = rc2CSP.CreateEncryptor(Convert.FromBase64String(c_key), Convert.FromBase64String(c_iv)); 
     using (MemoryStream msEncrypt = new MemoryStream()) 
     { 
      using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) 
      { 
       byte[] toEncrypt = Encoding.Unicode.GetBytes(openText); 

       csEncrypt.Write(toEncrypt, 0, toEncrypt.Length); 
       csEncrypt.FlushFinalBlock(); 

       byte[] encrypted = msEncrypt.ToArray(); 

       return Convert.ToBase64String(encrypted); 
      } 
     } 
    } 

    public static string DecryptText(string encryptedText) 
    { 
     RC2CryptoServiceProvider rc2CSP = new RC2CryptoServiceProvider(); 
     ICryptoTransform decryptor = rc2CSP.CreateDecryptor(Convert.FromBase64String(c_key), Convert.FromBase64String(c_iv)); 
     using (MemoryStream msDecrypt = new MemoryStream(Convert.FromBase64String(encryptedText))) 
     { 
      using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) 
      { 
       List<Byte> bytes = new List<byte>(); 
       int b; 
       do 
       { 
        b = csDecrypt.ReadByte(); 
        if (b != -1) 
        { 
         bytes.Add(Convert.ToByte(b)); 
        } 

       } 
       while (b != -1); 

       return Encoding.Unicode.GetString(bytes.ToArray()); 
      } 
     } 
    } 
+0

На всякий случай, если вы хотите знать, что они заполнены случайными и действительными данными 'c_iv' и' c_key', в экземпляре 'RC2CryptoServiceProvider' есть свойство' Key' и 'IV'. –

+5

Ваше неправильное использование. Вся суть IV должна отличаться для каждого шифрования. Не используйте константу IV. – CodesInChaos

0
string clearText = txtPassword.Text; 
     string EncryptionKey = "MAKV2SPBNI99212"; 
     byte[] clearBytes = Encoding.Unicode.GetBytes(clearText); 
     using (Aes encryptor = Aes.Create()) 
     { 
      Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 }); 
      encryptor.Key = pdb.GetBytes(32); 
      encryptor.IV = pdb.GetBytes(16); 
      using (MemoryStream ms = new MemoryStream()) 
      { 
       using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write)) 
       { 
        cs.Write(clearBytes, 0, clearBytes.Length); 
        cs.Close(); 
       } 
       clearText = Convert.ToBase64String(ms.ToArray()); 
      } 
     } 
0

Сначала нужно создать класс, как:

public class Encryption 
    { 
     public static string Encrypt(string clearText) 
     { 
      string EncryptionKey = "MAKV2SPBNI99212"; 
      byte[] clearBytes = Encoding.Unicode.GetBytes(clearText); 
      using (Aes encryptor = Aes.Create()) 
      { 
       Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 }); 
       encryptor.Key = pdb.GetBytes(32); 
       encryptor.IV = pdb.GetBytes(16); 
       using (MemoryStream ms = new MemoryStream()) 
       { 
        using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write)) 
        { 
         cs.Write(clearBytes, 0, clearBytes.Length); 
         cs.Close(); 
        } 
        clearText = Convert.ToBase64String(ms.ToArray()); 
       } 
      } 
      return clearText; 
     } 

     public static string Decrypt(string cipherText) 
     { 
      string EncryptionKey = "MAKV2SPBNI99212"; 
      byte[] cipherBytes = Convert.FromBase64String(cipherText); 
      using (Aes encryptor = Aes.Create()) 
      { 
       Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 }); 
       encryptor.Key = pdb.GetBytes(32); 
       encryptor.IV = pdb.GetBytes(16); 
       using (MemoryStream ms = new MemoryStream()) 
       { 
        using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write)) 
        { 
         cs.Write(cipherBytes, 0, cipherBytes.Length); 
         cs.Close(); 
        } 
        cipherText = Encoding.Unicode.GetString(ms.ToArray()); 
       } 
      } 
      return cipherText; 
     } 
    } 

** В контроллере **

добавить ссылку для этого класса шифрования:

using testdemo.Models 

public ActionResult Index() { 
      return View(); 
     } 
     [HttpPost] 
     public ActionResult Index(string text) 
     { 
      if (Request["txtEncrypt"] != null) 
      { 
       string getEncryptionCode = Request["txtEncrypt"]; 
       string DecryptCode = Encryption.Decrypt(HttpUtility.UrlDecode(getEncryptionCode)); 
       ViewBag.GetDecryptCode = DecryptCode; 
       return View(); 
      } 
      else { 
       string getDecryptCode = Request["txtDecrypt"]; 
       string EncryptionCode = HttpUtility.UrlEncode(Encryption.Encrypt(getDecryptCode)); 
       ViewBag.GetEncryptionCode = EncryptionCode; 
       return View(); 
      } 

     } 

В View

<h2>Decryption Code</h2> 
@using (Html.BeginForm()) 
{ 
    <table class="table-bordered table"> 
     <tr> 
      <th>Encryption Code</th> 
      <td><input type="text" id="txtEncrypt" name="txtEncrypt" placeholder="Enter Encryption Code" /></td> 
     </tr> 
     <tr> 
      <td colspan="2"> 
       <span style="color:red">@ViewBag.GetDecryptCode</span> 
      </td> 
     </tr> 
     <tr> 
       <td colspan="2"> 
        <input type="submit" id="btnEncrypt" name="btnEncrypt"value="Decrypt to Encrypt code" /> 
       </td> 
      </tr> 
    </table> 
} 
    <br /> 
    <br /> 
    <br /> 
    <h2>Encryption Code</h2> 
@using (Html.BeginForm()) 
{ 
    <table class="table-bordered table"> 
     <tr> 
      <th>Decryption Code</th> 
      <td><input type="text" id="txtDecrypt" name="txtDecrypt" placeholder="Enter Decryption Code" /></td> 
     </tr> 

     <tr> 
      <td colspan="2"> 
       <span style="color:red">@ViewBag.GetEncryptionCode</span> 
      </td> 
     </tr> 
     <tr> 
      <td colspan="2"> 
       <input type="submit" id="btnDecryt" name="btnDecryt" value="Encrypt to Decrypt code" /> 
      </td> 
     </tr> 
    </table> 
} 
Смежные вопросы