C#加密算法

时间:2011-05-23 12:14:44

标签: c# encryption

互联网上有许多关于加密的答案,但我一直无法找到我正在寻找的内容:使用c#提供的加密字符串和文本文件的简单强加密。

我的主要问题是我不知道如何将IV保存到文本文件的开头或如何创建随机IV。我有一个关于加密流的例子,我在DES上看到了一个例子,但他们使用相同的IV和密钥,这是(通过知道的)不是一件好事。

3 个答案:

答案 0 :(得分:2)

你是对的,使用相同的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);
                }
            }
        }
    }
}

答案 1 :(得分:0)

请参见以下链接中的示例,它将使用哈希,盐和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());
        }
    }
}

答案 2 :(得分:0)

现在,AesGcm是适合使用的类和算法。易于找到的示例代码,其API也相当简单。

要生成IV / nonce,请使用RandomNumberGenerator.Fill填充一个正确大小的数组,对于AES-GCM,该数组的大小为12个字节(96位)。 RandomNumberGenerator是密码安全的。

至于将IV写入文件,这取决于您。您正在写入文件流吗?然后开始编写IV,然后继续编写密文。对于AES-GCM,我们还将编写标签,该标签不仅可以提供加密,还可以提供经过身份验证的加密,即在解密时,我们可以确认密文没有被篡改。

当读回这样的文件时,我们分别读取每个组件-IV,密文和标记。因为您知道如何编写它们,所以您知道如何阅读它们。例如,x字节IV,然后y字节标记,然后是其余字节密文,如果那是您将数据写入文件的方式。

将组件传递到AesGcm.Decrypt,瞧瞧。