.NET中的密码加密/解密代码
你在这里。我发现它在互联网上的某个地方。适合我。
/// <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);
}
很好的答案,我没有理解保护方法的范围部分。我谷歌它,我发现你可以使用DataProtection.CurrentUser。这可以吗?还是会在解密时带来问题?你能解释你做什么来创建你的范围类。谢谢。 – euther 2011-01-14 14:27:54
也许我错了,但它看起来像这种解决方案不能跨用户/机器移植,因此不适合存储加密数据。从文档中:“DPAPI将关键数据存储在用户配置文件中”。如果您使用此方法来加密和存储数据,那么如果您重新构建服务器,则无法从其他计算机检索和解密数据,或者无法使用天堂。 – Brett 2011-08-25 14:21:38
Visual Studio不能识别“范围”? – 2013-06-08 14:26:03
编辑:这是一个非常古老的答案。 2011年,SHA1已被弃用,现在在实践中已被打破。 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));
}
SHA1已被破坏,如下所示:http://okami-infosec.blogspot.com/2007/01/hash-sha-1-compromised.html – 2009-11-05 06:50:39
我不相信任何SHA-2家族已被妥协,你可能想要使用其中的一个:http://en.wikipedia.org/wiki/SHA_hash_functions#SHA-2_family – 2009-11-05 06:52:11
但是,这取决于你会如何安全或多么偏执。在大学我非常偏执。 – 2009-11-05 06:53:06
一个加密的最简单的方法(如果你绝对必须做一个了自己,因为.NET有这种令人敬畏的加密库已经[正如我之前的Cogwheel所提供])是将输入字符串的每个字符的ASCII值与已知的“键”值进行异或运算。我相信C#中的异或功能是使用^键实现的。
然后,您可以将值从XOR的结果转换回ASCII字符,并将它们存储在数据库中。这不是非常安全,但它是最简单的加密方法之一。
此外,如果使用访问数据库,我发现在打开数据库本身时,将某些字符放在字符串前会使整个字段无法读取。但即使对于恶意用户而言,该字段仍然可以被您的应用程序读取。但是谁又使用访问权呢?
这个问题会回答如何加密/解密: Encrypt and decrypt a string
您没有指定一个数据库,但是你会想基于64位编码它,使用Convert.toBase64String。 举一个例子,你可以使用: http://www.opinionatedgeek.com/Blog/blogentry=000361/BlogEntry.aspx
因此,或者将其保存在VARCHAR或CLOB,这取决于你加密的消息是多久,但密码为varchar应该工作。
上面的例子也以base64解码后覆盖解密
UPDATE:
实际上你可能不需要使用base64编码,但我发现它的帮助,如果我想打印它,或通过网络发送它。如果消息足够长,我发现先压缩它然后加密是有帮助的,因为当消息已经是二进制形式时,使用暴力更加困难,所以很难判断何时成功破解加密。
除了可移植性,使用base-64而不是二进制(如果db支持它)有什么实质性的好处吗? – Cogwheel 2009-11-05 05:59:30
没有好处,其他而不是事实上它更容易存储,作为一个字符串对待,如果你需要移动它,我发现它更容易。我不是使用blob的粉丝,主要是因为我花了这么长时间在mysql他们真的没有支持,所以我只是这么想。另外,如果你想打印出加密的消息,那么它就是可打印的方式,这可以很方便,只是为了看看发生了什么。 – 2009-11-05 06:14:14
好点...我在调试过程中将散列转换为字符串一次,并比较了最终的汉字> Cogwheel 2009-11-05 06:31:55
您可以使用托管的.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);
}
1)错误的方法名称,因为你散列和不加密。 2)不要使用快速散列来散列密码。一次SHA-2迭代不够好。使用scrypt,bcrypt或PBKDF2。这也不是问题的答案,因为OP需要可逆性。 – CodesInChaos 2013-01-10 14:26:37
我使用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_iv和c_key,在RC2CryptoServiceProvider实例中有一个属性'Key'和'IV'。 – 2012-11-14 19:03:39
你的IV使用不正确。对于每种加密,IV的全部要点是不同的。不要使用常量IV。 – CodesInChaos 2013-01-10 14:29:45
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());
}
}
首先创建一个类,如:
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>
}
是否有任何特殊原因需要检索?大多数时候你可以简单地使用散列函数来存储它。然后,当他们输入密码时,您将他们的条目进行散列并进行比较 – Cogwheel 2009-11-05 05:41:54