расшифровать зашифрованную строку во время другого запуска - PullRequest
0 голосов
/ 21 января 2020

Код ниже работает отлично и шифрует:

hello world

до:

BgGUY2eR7GfumjbQr58tBQ==

для запуска. В следующий раз это может быть иначе, например:

CYIM7V/h3iXu5PYzwmQ33g==

Я думаю, что в этом смысл этого алгоритма. Как мне расшифровать строку, которая была зашифрована некоторое время назад?

Если я сделаю:

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==");
    }

}

Я получу:

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) 

Есть идеи? Как я могу расшифровать строку, зашифрованную в прошлом, с помощью ключа? Спасибо!

Рабочий код:

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

1 Ответ

2 голосов
/ 21 января 2020

Вы генерируете новый (случайный) вектор инициализации при каждом дешифровании. Вы должны использовать тот же IV при расшифровке, который использовался при шифровании.

Ваш пример кода работает, потому что он использует одно и то же состояние al go (включая IV) для шифрования и дешифрования в одном и том же цикле, но не будет работать между сериями, поскольку GenerateIV создает новый случайный буфер каждый раз время.

Обычно можно записать IV перед зашифрованным значением и затем сохранить их вместе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...