如何在c#中加密和解密字符串?
当前回答
一个安全散列数据的好算法是BCrypt:
除了加入盐来抵御彩虹桌的攻击, Bcrypt是一个自适应函数:随着时间的推移,迭代计数可以 增加使它变慢,所以它仍然抵抗蛮力 搜索攻击,即使增加计算能力。
BCrypt有一个很好的。net实现,也可以作为NuGet包使用。
其他回答
我在这里复制了一个类似问题的答案:c#的简单双向加密。
基于多个答案和评论。
加密文本前的随机初始化向量(@jbtule) 使用TransformFinalBlock()代替MemoryStream (@RenniePet) 没有预填充键,以避免任何人复制和粘贴灾难 正确处理和使用模式
代码:
/// <summary>
/// Simple encryption/decryption using a random initialization vector
/// and prepending it to the crypto text.
/// </summary>
/// <remarks>Based on multiple answers in https://stackoverflow.com/questions/165808/simple-two-way-encryption-for-c-sharp </remarks>
public class SimpleAes : IDisposable
{
/// <summary>
/// Initialization vector length in bytes.
/// </summary>
private const int IvBytes = 16;
/// <summary>
/// Must be exactly 16, 24 or 32 characters long.
/// </summary>
private static readonly byte[] Key = Convert.FromBase64String("FILL ME WITH 16, 24 OR 32 CHARS");
private readonly UTF8Encoding _encoder;
private readonly ICryptoTransform _encryptor;
private readonly RijndaelManaged _rijndael;
public SimpleAes()
{
_rijndael = new RijndaelManaged {Key = Key};
_rijndael.GenerateIV();
_encryptor = _rijndael.CreateEncryptor();
_encoder = new UTF8Encoding();
}
public string Decrypt(string encrypted)
{
return _encoder.GetString(Decrypt(Convert.FromBase64String(encrypted)));
}
public void Dispose()
{
_rijndael.Dispose();
_encryptor.Dispose();
}
public string Encrypt(string unencrypted)
{
return Convert.ToBase64String(Encrypt(_encoder.GetBytes(unencrypted)));
}
private byte[] Decrypt(byte[] buffer)
{
// IV is prepended to cryptotext
byte[] iv = buffer.Take(IvBytes).ToArray();
using (ICryptoTransform decryptor = _rijndael.CreateDecryptor(_rijndael.Key, iv))
{
return decryptor.TransformFinalBlock(buffer, IvBytes, buffer.Length - IvBytes);
}
}
private byte[] Encrypt(byte[] buffer)
{
// Prepend cryptotext with IV
byte[] inputBuffer = _rijndael.IV.Concat(buffer).ToArray();
return _encryptor.TransformFinalBlock(inputBuffer, IvBytes, buffer.Length);
}
}
下面的示例演示如何加密和解密示例数据:
// This constant is used to determine the keysize of the encryption algorithm in bits.
// We divide this by 8 within the code below to get the equivalent number of bytes.
private const int Keysize = 128;
// This constant determines the number of iterations for the password bytes generation function.
private const int DerivationIterations = 1000;
public static string Encrypt(string plainText, string passPhrase)
{
// Salt and IV is randomly generated each time, but is preprended to encrypted cipher text
// so that the same Salt and IV values can be used when decrypting.
var saltStringBytes = GenerateBitsOfRandomEntropy(16);
var ivStringBytes = GenerateBitsOfRandomEntropy(16);
var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
{
var keyBytes = password.GetBytes(Keysize / 8);
using (var symmetricKey = new RijndaelManaged())
{
symmetricKey.BlockSize = 128;
symmetricKey.Mode = CipherMode.CBC;
symmetricKey.Padding = PaddingMode.PKCS7;
using (var encryptor = symmetricKey.CreateEncryptor(keyBytes, ivStringBytes))
{
using (var memoryStream = new MemoryStream())
{
using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
{
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
cryptoStream.FlushFinalBlock();
// Create the final bytes as a concatenation of the random salt bytes, the random iv bytes and the cipher bytes.
var cipherTextBytes = saltStringBytes;
cipherTextBytes = cipherTextBytes.Concat(ivStringBytes).ToArray();
cipherTextBytes = cipherTextBytes.Concat(memoryStream.ToArray()).ToArray();
memoryStream.Close();
cryptoStream.Close();
return Convert.ToBase64String(cipherTextBytes);
}
}
}
}
}
}
public static string Decrypt(string cipherText, string passPhrase)
{
// Get the complete stream of bytes that represent:
// [32 bytes of Salt] + [32 bytes of IV] + [n bytes of CipherText]
var cipherTextBytesWithSaltAndIv = Convert.FromBase64String(cipherText);
// Get the saltbytes by extracting the first 32 bytes from the supplied cipherText bytes.
var saltStringBytes = cipherTextBytesWithSaltAndIv.Take(Keysize / 8).ToArray();
// Get the IV bytes by extracting the next 32 bytes from the supplied cipherText bytes.
var ivStringBytes = cipherTextBytesWithSaltAndIv.Skip(Keysize / 8).Take(Keysize / 8).ToArray();
// Get the actual cipher text bytes by removing the first 64 bytes from the cipherText string.
var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((Keysize / 8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((Keysize / 8) * 2)).ToArray();
using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
{
var keyBytes = password.GetBytes(Keysize / 8);
using (var symmetricKey = new RijndaelManaged())
{
symmetricKey.BlockSize = 128;
symmetricKey.Mode = CipherMode.CBC;
symmetricKey.Padding = PaddingMode.PKCS7;
using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, ivStringBytes))
{
using (var memoryStream = new MemoryStream(cipherTextBytes))
{
using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
{
var plainTextBytes = new byte[cipherTextBytes.Length];
var decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
memoryStream.Close();
cryptoStream.Close();
return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
}
}
}
}
}
}
private static byte[] GenerateBitsOfRandomEntropy(int size)
{
// 32 Bytes will give us 256 bits.
// 16 Bytes will give us 128 bits.
var randomBytes = new byte[size];
using (var rngCsp = new RNGCryptoServiceProvider())
{
// Fill the array with cryptographically secure random bytes.
rngCsp.GetBytes(randomBytes);
}
return randomBytes;
}
加密
public string EncryptString(string inputString)
{
MemoryStream memStream = null;
try
{
byte[] key = { };
byte[] IV = { 12, 21, 43, 17, 57, 35, 67, 27 };
string encryptKey = "aXb2uy4z"; // MUST be 8 characters
key = Encoding.UTF8.GetBytes(encryptKey);
byte[] byteInput = Encoding.UTF8.GetBytes(inputString);
DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
memStream = new MemoryStream();
ICryptoTransform transform = provider.CreateEncryptor(key, IV);
CryptoStream cryptoStream = new CryptoStream(memStream, transform, CryptoStreamMode.Write);
cryptoStream.Write(byteInput, 0, byteInput.Length);
cryptoStream.FlushFinalBlock();
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
return Convert.ToBase64String(memStream.ToArray());
}
解密:
public string DecryptString(string inputString)
{
MemoryStream memStream = null;
try
{
byte[] key = { };
byte[] IV = { 12, 21, 43, 17, 57, 35, 67, 27 };
string encryptKey = "aXb2uy4z"; // MUST be 8 characters
key = Encoding.UTF8.GetBytes(encryptKey);
byte[] byteInput = new byte[inputString.Length];
byteInput = Convert.FromBase64String(inputString);
DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
memStream = new MemoryStream();
ICryptoTransform transform = provider.CreateDecryptor(key, IV);
CryptoStream cryptoStream = new CryptoStream(memStream, transform, CryptoStreamMode.Write);
cryptoStream.Write(byteInput, 0, byteInput.Length);
cryptoStream.FlushFinalBlock();
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
Encoding encoding1 = Encoding.UTF8;
return encoding1.GetString(memStream.ToArray());
}
我有一个名为X509Crypto的开源项目,它利用证书来加密和解密字符串。它很容易使用。下面是一个如何使用它的例子:
1. 2 .使用X509Crypto命令行生成新的加密证书和密钥对
>x509crypto.exe
X509Crypto> makecert -context user -keysize medium -alias myvault
Certificate with thumbprint B31FE7E7AE5229F8186782742CF579197FA859FD was added to X509Alias "myvault" in the user X509Context
X509Crypto>
2. 使用Encrypt CLI命令向新的X509Alias添加一个秘密
X509Crypto> encrypt -text -alias myvault -context user -secret apikey -in "80EAF03248965AC2B78090"
Secret apikey has been added to X509Alias myvault in the user X509Context
X509Crypto>
3.在程序中引用该秘密
一旦你建立了一个X509Alias并添加了你的秘密,在你的程序中使用Org检索它们是很简单的。X509Crypto nuget包安装:
using Org.X509Crypto;
namespace SampleApp
{
class Program
{
static void Main(string[] args)
{
var Alias = new X509Alias(@"myvault", X509Context.UserReadOnly);
var apiKey = Alias.RecoverSecret(@"apikey");
}
}
}
加密是编程中非常常见的问题。我认为最好是安装一个包来为您做这个任务。也许是一个简单的开源NuGet项目 简单Aes加密
密钥在配置文件中,因此很容易在生产环境中更改,而且我没有看到任何缺点。
<MessageEncryption>
<EncryptionKey KeySize="256" Key="3q2+796tvu/erb7v3q2+796tvu/erb7v3q2+796tvu8="/>
</MessageEncryption>
推荐文章
- 为什么在Java和。net中不能修改字符串?
- 在EF中更新父实体时如何添加/更新子实体
- ASP。NET身份的默认密码散列器-它是如何工作的,它是安全的?
- 如何写一个JSON文件在c# ?
- 静态隐式运算符
- 不区分大小写列表搜索
- 'throw'和'throw new Exception()'的区别
- 不能在lambda表达式中使用ref或out参数
- c# int到字节[]
- 如何跟踪log4net问题
- 将WPF组合框绑定到自定义列表
- 为什么质数在密码学中很重要?
- foreach vs somlist . foreach (){}
- 为什么try{…}最后{…}好;尝试{…} catch{}坏?
- c# 8用多种情况切换表达式,结果相同