C#加密算法
本文关键字:加密算法 | 更新日期: 2023-09-27 17:57:38
互联网上有很多关于加密的答案,但我一直无法找到我想要的东西:使用c#提供的加密字符串和文本文件的工具进行简单的强加密。
我的主要问题是,我不知道如何将IV保存到文本文件的开头,也不知道如何创建随机IV。我有一个关于加密流的例子,我也看到了一个关于DES的例子,但他们使用了相同的IV和密钥,这(据我所知)不是一件好事。
您是对的,使用相同的IV是一种糟糕的做法,尤其是如果Key或IV都是硬编码的。我建议使用AesManaged
类。它使用AES算法,即当前的标准。生成IV相当简单:
var aes = new AesManaged(); //Set your KeySize if you will generate a key too.
aes.GenerateIV();
var iv = aes.IV;
这是一种获取新初始化向量的简单方法。如果您的目标是加密文件,您可以存储该文件,但您将如何处理密钥?在应用程序中对其进行硬编码通常不是一个很好的方法。如果你的应用程序是基于密码的,那么你可以从Rfc2898DeriveBytes生成密钥,以获得基于密码的字节数组。这样,您的应用程序就永远不知道加密密钥是什么
下面是一个将IV写入文件,然后写入文件内容的示例。
using (AesManaged aes = new AesManaged())
{
//Set the Key here.
aes.GenerateIV();
using (var transform = aes.CreateEncryptor())
{
using (var fileStream = new FileStream("C:''in.txt", FileMode.Open))
{
using (var saveTo = new FileStream("C:''out.txt", FileMode.Create))
{
using (var cryptoStream = new CryptoStream(saveTo, transform,CryptoStreamMode.Write))
{
var iv = aes.IV;
cryptoStream.Write(iv, 0, iv.Length);
fileStream.CopyTo(cryptoStream);
}
}
}
}
}
请参阅下面链接上的示例,它将创建一个使用hash、salt和VI密钥的字符串加密。
https://github.com/salahuddinuk/Encryption-Decryption/blob/master/EncryptDecrypt/Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace EncryptDecrypt
{
public partial class Form1 : Form
{
static readonly string PasswordHash = "P!!Sw0rd~";
static readonly string SaltKey = "Sa~LT~KEY";
static readonly string VIKey = "@1B2c3D4@e5F6<7H8<.";
public Form1()
{
InitializeComponent();
}
private void btn_Process_Click(object sender, EventArgs e)
{
try
{
lbl_Error.Text = "";
if (chb_Decrypt.Checked == true)
txt_Result.Text = Decrypt(txt_Value.Text);
else
txt_Result.Text = Encrypt(txt_Value.Text);
}
catch (Exception ex)
{
lbl_Error.Text = ex.Message;
}
}
public static string Encrypt(string plainText)
{
byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);
var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.Zeros };
var encryptor = symmetricKey.CreateEncryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey));
byte[] cipherTextBytes;
using (var memoryStream = new MemoryStream())
{
using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
{
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
cryptoStream.FlushFinalBlock();
cipherTextBytes = memoryStream.ToArray();
cryptoStream.Close();
}
memoryStream.Close();
}
return Convert.ToBase64String(cipherTextBytes);
}
public static string Decrypt(string encryptedText)
{
byte[] cipherTextBytes = Convert.FromBase64String(encryptedText);
byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);
var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.None };
var decryptor = symmetricKey.CreateDecryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey));
var memoryStream = new MemoryStream(cipherTextBytes);
var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
byte[] plainTextBytes = new byte[cipherTextBytes.Length];
int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
memoryStream.Close();
cryptoStream.Close();
return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount).TrimEnd("'0".ToCharArray());
}
}
}
如今,AesGcm
将是一个合适的类和算法。它的示例代码很容易找到,而且它的API相当简单。
要生成IV/随机数,请使用RandomNumberGenerator.Fill
填充正确大小的数组,AES-GCM为12字节(96位)。CCD_ 4是密码安全的一种。
至于将IV写入文件,则由您决定。你在向文件流写入吗?然后从写IV开始,然后继续写密文。对于AES-GCM,我们还将编写标签,这不仅会给我们加密,还会给我们认证加密,即在解密时,我们可以确认密文没有被篡改。
当重新读取这样的文件时,我们分别读取每个组件——IV、密文和标签。既然你知道你是如何写的,你就知道如何阅读它们。例如,x字节IV,然后是y字节标记,然后是剩余的字节密文,如果这就是将数据写入文件的方式。
将组件传递给AesGcm.Decrypt
并瞧。