2

There are many answers on the internet regarding encryption, but I have been unable to find exactly what I'm looking for: simple strong encryption using the tools that c# provides to encrypt strings and text files.

My main problem is that I don't know how to save the IV into the beginning of the text file or how to create a random IV. I have an example on crypto stream and I have seen an example on DES, but they use the same IV and key and that is (by what I know) not a good thing to do.

4
  • There are dozens upon dozens of examples of how to do this in C# on this website have you looked? Care to explain the purpose behind encrypting the strings and text files, if your application will have the ability to decrypt the files and strings, you should know the security risk of doing so. Commented May 23, 2011 at 12:17
  • A nice class is SecureString! Try look here: msdn.microsoft.com/it-it/library/… Commented May 23, 2011 at 12:21
  • @danyolgiax: In case people prefer English: msdn.microsoft.com/en-us/library/…, which incidentally contains the highquality community comment link to msdn.microsoft.com/en-us/library/… as well Commented May 23, 2011 at 12:28
  • 3
    You have discovered an important truth about crypto: the math is easy; it's the key management that's hard. Remember that what crypto does is it makes the secrecy of the data equal to the secrecy of the key; all it does is make the thing you have to keep secret smaller. You still have the hard problem of keeping a secret actually secret. Commented May 23, 2011 at 14:16

3 Answers 3

2

You're right, using the same IV is a bad practice, especially if either the Key or IV are hard coded. I'd recommend using the AesManaged class. It uses the AES algorithm, the current standard. Generating an IV is fairly simple:

var aes = new AesManaged(); //Set your KeySize if you will generate a key too.
aes.GenerateIV();
var iv = aes.IV;

That's a simple way of getting a new initialization vector. If your goal is to encrypt a file, you can store the File, but what will you do with the Key? Hard coding it within your application is generally not a very good way of doing it. If your application will be password based, then you can generate the key from Rfc2898DeriveBytes to get a byte array based on a password. This way, your application never knows what the encryption key is.

Here is an example for writing the IV to a file, then the file contents.

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);
                }
            }
        }
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

first of all thank you for the answer :) secondly i have a problem with understanding one thing.. i understand that hard coding the key is a problem, but if my program doesn't know the encryption key than how can i decrypt the file later? meaning, if for instance the program encrypted the file and then after that for example it crashed, i am left with an encrypted file and i know nothing about the key, so the information is lost to me and i cannot restore the information that was encrypted.
0

see the example on following link, it will create a string encryption with hash, salt and VI key.

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());
        }
    }
}

Comments

0

Nowadays, AesGcm would be an appropriate class and algorithm to use. Examples code for it is easy enough to find, and its API is fairly straightforward.

To generate the IV/nonce, use RandomNumberGenerator.Fill to populate an array of the correct size, which is 12 bytes (96 bits) for AES-GCM. RandomNumberGenerator is the cryptographically-secure one.

As for writing the IV to the file, that is up to you. Are you writing to a file stream? Then start by writing the IV, and then proceed to write the ciphertext. For AES-GCM, we would also write the tag, which will give us not just encryption, but authenticated encryption, i.e. on decryption we can confirm that the ciphertext has not been tampered with.

When reading such a file back in, we read each of the components separately - IV, ciphertext, and tag. Since you know how you wrote them, you know how to read them. For example, x bytes IV, then y bytes tag, then the remaining bytes ciphertext, if that is how you wrote the data to the file.

Pass the components to AesGcm.Decrypt and voila.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.