[英]Password encryption/decryption code in .NET
我想要在C#中對密碼進行簡單的加密和解密。 如何將密碼以加密格式保存在數據庫中並通過解密以原始格式檢索?
干得好。 我在互聯網上的某個地方找到了它。 對我來說效果很好。
/// <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);
}
編輯:這是一個非常古老的答案。 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));
}
我使用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());
}
}
}
這個問題將回答如何加密/解密: 在C#中加密和解密字符串?
您沒有指定數據庫,但是您想使用Convert.toBase64String對它進行base-64編碼。 例如,您可以使用: http : //www.opinionatedgeek.com/Blog/blogentry=000361/BlogEntry.aspx
然后,您可以將其保存在varchar或blob中,具體取決於加密消息的長度,但是對於密碼varchar應該可以工作。
上面的示例還將介紹解碼base64之后的解密。
更新:
實際上,您可能不需要使用base64編碼,但是我發現它很有用,以防萬一我想打印它或通過Web發送它。 如果消息足夠長,則最好先對其進行壓縮,然后再進行加密,因為當消息已經是二進制形式時,很難使用蠻力,因此很難確定何時成功破壞了加密。
首先創建一個類似的類:
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();
}
}
視野中
<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>
}
最簡單的加密方法之一(如果由於.NET已經具有如此出色的加密庫(如我之前的Cogwheel所提供的那樣,所以您必須絕對自己做一個))是將輸入字符串的每個字符的ASCII值與已知的“鍵”值。 我相信C#中的XOR功能是使用^鍵完成的。
然后,您可以將值從XOR的結果轉換回ASCII字符,並將其存儲在數據庫中。 這不是高度安全,但是它是最簡單的加密方法之一。
另外,如果使用Access數據庫,我發現打開數據庫本身時,某些字符放在字符串前面會使整個字段不可讀。 但是,即使對於惡意用戶而言,該字段仍為空白,但您的應用仍然可以讀取該字段。 但是,誰仍然使用訪問權呢?
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());
}
}
不要加密/解密密碼,這是一個重大的安全漏洞。 使用強大的哈希算法(例如PBKDF2,bcrypt,scrypts或Argon)來哈希密碼。
用戶設置密碼后,對其進行哈希處理並存儲哈希值(和鹽)。
用戶登錄時,請重新哈希提供的密碼,並將其與數據庫中的哈希進行比較。
您可以使用托管的.Net加密庫,然后將加密的字符串保存到數據庫中。 當你要驗證的密碼,您可以比較存儲的數據庫中的字符串與用戶輸入的哈希值。 有關SHA512Managed的更多信息,請參見此處
使用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);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.