decrypt encrypted string during different run

0

The code below works fine and encrypts:

hello world

to:

BgGUY2eR7GfumjbQr58tBQ==

for a run. The next time this may be different, for example:

CYIM7V/h3iXu5PYzwmQ33g==

I think this is the point of this algorithm. How do I decrypt a string that was encrypted a while back?

If I do:

static void Main(string[] args)
{
    var key = @"abcdefghijklmnopqrstuvw==";

    using (var aesAlg = Aes.Create())
    {
    aesAlg.Mode = CipherMode.CBC;
    aesAlg.Padding = PaddingMode.PKCS7;
    aesAlg.Key = Convert.FromBase64String(key);
    aesAlg.GenerateIV();

    var decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
    var helloWorld = DecryptProperty(decryptor, "CYIM7V/h3iXu5PYzwmQ33g==");
    }

}

I get:

System.Security.Cryptography.CryptographicException
  HResult=0x80131430
  Message=Padding is invalid and cannot be removed.
  Source=System.Core
  StackTrace:
   at System.Security.Cryptography.CapiSymmetricAlgorithm.DepadBlock(Byte[] block, Int32 offset, Int32 count)
   at System.Security.Cryptography.CapiSymmetricAlgorithm.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
   at System.Security.Cryptography.CryptoStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at System.IO.StreamReader.ReadBuffer()
   at System.IO.StreamReader.ReadToEnd()
   at crypt.Program.DecryptProperty(ICryptoTransform decryptor, String valueToDecrypt) 

Any ideas? How can I decrypt a string encrypted in the past using the key? Thanks!

Working code:

using System;
using System.IO;
using System.Security.Cryptography;

namespace crypt
{
    class Program
    {
        static void Main(string[] args)
        {
            var key = @"abcdefghijklmnopqrstuvw==";

            using (var aesAlg = Aes.Create())
            {
                aesAlg.Mode = CipherMode.CBC;
                aesAlg.Padding = PaddingMode.PKCS7;
                aesAlg.Key = Convert.FromBase64String(key);
                aesAlg.GenerateIV();

                var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
                var encHelloWorld = EncryptProperty(encryptor, "hello world");

                var decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
                var helloWorld = DecryptProperty(decryptor, encHelloWorld);
            }

        }
        private static string EncryptProperty(ICryptoTransform encryptor, string valueToEncrypt)
        {
            byte[] encrypted;
            using (var msEncrypt = new MemoryStream())
            {
                using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (var swEncrypt = new StreamWriter(csEncrypt))
                    {
                        swEncrypt.Write(valueToEncrypt);
                    }
                    encrypted = msEncrypt.ToArray();
                }
            }
            return Convert.ToBase64String(encrypted);
        }

        private static string DecryptProperty(ICryptoTransform decryptor, string valueToDecrypt)
        {
            string decrypted;

            using (var msDecrypt = new MemoryStream(Convert.FromBase64String(valueToDecrypt)))
            {
                using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    using (var srDecrypt = new StreamReader(csDecrypt))
                    {
                        decrypted = srDecrypt.ReadToEnd();
                    }
                }
            }
            return decrypted;
        }
    }
}
c#
encryption
asked on Stack Overflow Jan 21, 2020 by cs0815

1 Answer

2

You are generating a new (random) Initialization Vector on every decrypt. You need to use the same IV when decrypting that was used when encrypting.

Your sample code works because it uses the same algo state (IV included) for encrypting and decrypting in the same run, but won't work across runs because GenerateIV creates a new random buffer every time.

Typically one would write the IV before the encrypted value and then store them together.

answered on Stack Overflow Jan 21, 2020 by Boris B.

User contributions licensed under CC BY-SA 3.0