如何在c#中加密和解密字符串?
当前回答
下面是一个使用RSA的例子。
重要:使用RSA加密KeySize - MinimumPadding加密的数据大小是有限制的。例如256字节(假设2048位密钥)- 42字节(最小OEAP填充)= 214字节(最大明文大小)
用RSA密钥替换your_rsa_key。
var provider = new System.Security.Cryptography.RSACryptoServiceProvider();
provider.ImportParameters(your_rsa_key);
var encryptedBytes = provider.Encrypt(
System.Text.Encoding.UTF8.GetBytes("Hello World!"), true);
string decryptedTest = System.Text.Encoding.UTF8.GetString(
provider.Decrypt(encryptedBytes, true));
更多信息,请访问MSDN - RSACryptoServiceProvider
其他回答
一个安全散列数据的好算法是BCrypt:
除了加入盐来抵御彩虹桌的攻击, Bcrypt是一个自适应函数:随着时间的推移,迭代计数可以 增加使它变慢,所以它仍然抵抗蛮力 搜索攻击,即使增加计算能力。
BCrypt有一个很好的。net实现,也可以作为NuGet包使用。
您必须使用System.Security.Cryptography来使用命名空间;usehash是bool类型,true或false。字符串变量“key”对于加密和解密应该是相同的
//Encryption
public string EncryptText(string toEncrypt, bool useHashing)
{
try
{
byte[] keyArray;
byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);
string key = "String Key Value"; //Based on this key stirng is encrypting
//System.Windows.Forms.MessageBox.Show(key);
//If hashing use get hashcode regards to your key
if (useHashing)
{
MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
//Always release the resources and flush data
//of the Cryptographic service provide. Best Practice
hashmd5.Clear();
}
else
keyArray = UTF8Encoding.UTF8.GetBytes(key);
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
//set the secret key for the tripleDES algorithm
tdes.Key = keyArray;
//mode of operation. there are other 4 modes. We choose ECB(Electronic code Book)
tdes.Mode = CipherMode.ECB;
//padding mode(if any extra byte added)
tdes.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = tdes.CreateEncryptor();
//transform the specified region of bytes array to resultArray
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
//Release resources held by TripleDes Encryptor
tdes.Clear();
//Return the encrypted data into unreadable string format
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
catch (Exception e)
{
throw e;
}
}
//Decryption
public string DecryptText(string cipherString, bool useHashing)
{
try
{
byte[] keyArray;
//get the byte code of the string
byte[] toEncryptArray = Convert.FromBase64String(cipherString);
string key = "String Key Value"; //Based on this key string is decrypted
if (useHashing)
{
//if hashing was used get the hash code with regards to your key
MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
//release any resource held by the MD5CryptoServiceProvider
hashmd5.Clear();
}
else
{
//if hashing was not implemented get the byte code of the key
keyArray = UTF8Encoding.UTF8.GetBytes(key);
}
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
//set the secret key for the tripleDES algorithm
tdes.Key = keyArray;
//mode of operation. there are other 4 modes.
//We choose ECB(Electronic code Book)
tdes.Mode = CipherMode.ECB;
//padding mode(if any extra byte added)
tdes.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = tdes.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock
(toEncryptArray, 0, toEncryptArray.Length);
//Release resources held by TripleDes Encryptor
tdes.Clear();
//return the Clear decrypted TEXT
return UTF8Encoding.UTF8.GetString(resultArray);
}
catch (Exception ex)
{
throw ex;
}
}
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
public class Program
{
public static void Main()
{
var key = Encoding.UTF8.GetBytes("SUkbqO2ycDo7QwpR25kfgmC7f8CoyrZy");
var data = Encoding.UTF8.GetBytes("testData");
//Encrypt data
var encrypted = CryptoHelper.EncryptData(data,key);
//Decrypt data
var decrypted = CryptoHelper.DecryptData(encrypted,key);
//Display result
Console.WriteLine(Encoding.UTF8.GetString(decrypted));
}
}
public static class CryptoHelper
{
public static byte[] EncryptData(byte[] data, byte[] key)
{
using (var aesAlg = Aes.Create())
{
aesAlg.Mode = CipherMode.CBC;
using (var encryptor = aesAlg.CreateEncryptor(key, aesAlg.IV))
{
using (var msEncrypt = new MemoryStream())
{
msEncrypt.Write(aesAlg.IV, 0, aesAlg.IV.Length);
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
csEncrypt.Write(data, 0, data.Length);
return msEncrypt.ToArray();
}
}
}
}
public static byte[] DecryptData(byte[] encrypted, byte[] key)
{
var iv = new byte[16];
Buffer.BlockCopy(encrypted, 0, iv, 0, iv.Length);
using (var aesAlg = Aes.Create())
{
aesAlg.Mode = CipherMode.CBC;
using (var decryptor = aesAlg.CreateDecryptor(key, iv))
{
using (var msDecrypt = new MemoryStream(encrypted, iv.Length, encrypted.Length - iv.Length))
{
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (var resultStream = new MemoryStream())
{
csDecrypt.CopyTo(resultStream);
return resultStream.ToArray();
}
}
}
}
}
}
}
这是一个简单的Snippet,最初由ASP Snippet编写
using System.Text;
using System.Security.Cryptography;
using System.IO;
private string Encrypt(string clearText)
{
string EncryptionKey = "yourkey";
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;
}
private string Decrypt(string cipherText)
{
string EncryptionKey = "yourkey";
cipherText = cipherText.Replace(" ", "+");
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;
}
免责声明:此解决方案只能用于未公开的静态数据(例如配置文件或DB)。只有在这种情况下,快速和肮脏的解决方案才能被认为比@jbtule的解决方案更好,因为它的维护更低。
原来的帖子: 我发现jbtule的答案对于一个快速和肮脏的安全AES字符串加密有点复杂,Brett的答案有一个错误,初始化向量是一个固定的值,使它容易受到填充攻击,所以我修复了Brett的代码,并添加了一个随机IV,添加到chitered字符串,创建一个不同的加密值,每个加密相同的值:
加密:
public static string Encrypt(string clearText)
{
byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
using (Aes encryptor = Aes.Create())
{
byte[] IV = new byte[15];
rand.NextBytes(IV);
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, IV);
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(IV) + Convert.ToBase64String(ms.ToArray());
}
}
return clearText;
}
解密:
public static string Decrypt(string cipherText)
{
byte[] IV = Convert.FromBase64String(cipherText.Substring(0, 20));
cipherText = cipherText.Substring(20).Replace(" ", "+");
byte[] cipherBytes = Convert.FromBase64String(cipherText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, IV);
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;
}
将EncryptionKey替换为您的密钥。 在我的实现中,密钥被保存在配置文件(web.config\app.config)中,因为您不应该将其硬编码保存。配置文件也应该加密,这样密钥就不会被保存为明文。
protected static string _Key = "";
protected static string EncryptionKey
{
get
{
if (String.IsNullOrEmpty(_Key))
{
_Key = ConfigurationManager.AppSettings["AESKey"].ToString();
}
return _Key;
}
}
推荐文章
- 防止在ASP中缓存。NET MVC中使用属性的特定操作
- 转换为值类型'Int32'失败,因为物化值为空
- c#中有任何连接字符串解析器吗?
- 在Linq中转换int到字符串到实体的问题
- 是否可以动态编译和执行c#代码片段?
- 创建自定义MSBuild任务时,如何从c#代码获取当前项目目录?
- MSBuild路径
- c#和Java的主要区别是什么?
- 在c#中创建一个特定时区的DateTime
- .NET中的属性是什么?
- csproj文件中的“Service Include”是干什么用的?
- 如何使用try catch进行异常处理是最佳实践
- 使用PyCrypto AES-256加密和解密
- 替换字符串中第一次出现的模式
- .NET中字节的字面后缀?