.NET中的密码加密/解密代码

我希望在C#中简单加密和解密密码。 如何在数据库中以加密格式保存密码,并通过解密检索原始格式?

干得好。 我发现它在互联网上的某个地方。 对我来说效果很好。

///  /// Encrypts a given password and returns the encrypted data /// as a base64 string. ///  /// An unencrypted string that needs /// to be secured. /// A base64 encoded string that represents the encrypted /// binary data. ///  /// This solution is not really secure as we are /// keeping strings in memory. If runtime protection is essential, ///  should be used. /// If  /// is a null reference. 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); } ///  /// Decrypts a given string. ///  /// A base64 encoded string that was created /// through the  or ///  extension methods. /// The decrypted string. /// Keep in mind that the decrypted string remains in memory /// and makes your application vulnerable per se. If runtime protection /// is essential,  should be used. /// If  /// is a null reference. 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)); } 

这个问题将回答如何加密/解密: 加密和解密字符串

您没有指定数据库,但是您需要使用Convert.toBase64String对其进行base-64编码。 有关示例,您可以使用: http : //www.opinionatedgeek.com/Blog/blogentry=000361/BlogEntry.aspx

然后,您可以将其保存在varchar或clob中,具体取决于加密消息的时长,但对于密码,varchar应该有效。

以上示例还将介绍解码base64后的解密

更新:

实际上,您可能不需要使用base64编码,但我发现它有用,以防我想要打印它,或通过网络发送它。 如果消息足够长,我发现首先压缩它然后加密是有帮助的,因为当消息已经是二进制forms时更难使用暴力,所以当你成功破坏加密时很难说。

我使用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 bytes = new List(); int b; do { b = csDecrypt.ReadByte(); if (b != -1) { bytes.Add(Convert.ToByte(b)); } } while (b != -1); return Encoding.Unicode.GetString(bytes.ToArray()); } } } 

首先创建一个类:

 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(); } } 

在视图中

 

Decryption Code

@using (Html.BeginForm()) {
Encryption Code
@ViewBag.GetDecryptCode
}


Encryption Code

@using (Html.BeginForm()) {
Decryption Code
@ViewBag.GetEncryptionCode
}

最简单的加密方法之一(如果你必须自己创建一个,因为.NET已经拥有如此强大的加密库[由我之前的Cogwheel提供])是对输入字符串的每个字符的ASCII值进行异或已知的“关键”值。 C#中的XORfunction是使用我认为的^键完成的。

然后,您可以将值从XOR的结果转换回ASCII Chars,并将它们存储在数据库中。 这不是很安全,但它是最简单的加密方法之一。

此外,如果使用访问数据库,我发现当放在字符串前面时,某些字符会在打开数据库本身时使整个字段不可读。 但是,即使对于恶意用户来说,该字段仍然可以被您的应用程序读取。 但是谁不再使用访问权限呢?

  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()); } } 

您可以使用托管的.Net加密库,然后将加密的字符串保存到数据库中。 如果要validation密码,可以将存储的数据库字符串与用户输入的散列值进行比较。 有关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); }