Нераспознанный Unicode-результат расшифровки AES - PullRequest
1 голос
/ 03 апреля 2020

Я пытаюсь создать простой помощник шифрования AES для шифрования / дешифрования некоторых строк. Кулак, у меня проблема с режимом заполнения, при расшифровке которого он принимает только, если в противном случае возникает ошибка об заполнении нуля! Вторая проблема - когда я пытаюсь зашифровать простую строку «Hello World», она зашифрована, и у меня есть строка base64, но при попытке расшифровки ошибки нет, но отображается странный неизвестный символ! как 㡲 啁 䎰 廾 ử 靱 힩 㡲 啁 䎰 廾 ử 靱 힩 Мой код:

        private static int keySizes = 256;
        private static int blockSize = 128;
        private static PaddingMode pMode = PaddingMode.Zeros;
        private static CipherMode cMode = CipherMode.ECB;
        private static byte[] key = GenEncryptionKey();
        private const string passphrase = @"StartYourMorningWithASmile";

    private static byte[] GenEncryptionKey()
    {
        HashAlgorithm hash = MD5.Create();
        return hash.ComputeHash(Encoding.Unicode.GetBytes(passphrase));
    }

    private static AesManaged CreateCryptor()
    {
        AesManaged cryptor = new AesManaged();
        cryptor.KeySize = keySizes;
        cryptor.BlockSize = blockSize;
        cryptor.Padding = pMode;
        cryptor.Key = key;
        cryptor.Mode = cMode;
        cryptor.GenerateIV();
        return cryptor;
    }
public static string EncryptParams(string reqVal)
        {
            string cipherText = "";

            if (string.IsNullOrEmpty(reqVal) || reqVal.Length < 1)
                throw new ArgumentNullException();
            byte[] plainBytes = Encoding.Unicode.GetBytes(reqVal);

            using (var cryptor = CreateCryptor())
            {
                ICryptoTransform encryptor = cryptor.CreateEncryptor();
                using (MemoryStream ms = new MemoryStream())
                {
                    using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                    {
                        cs.Write(plainBytes, 0, plainBytes.Length);

                    }
                    byte[] cipherBytes = ms.ToArray();
                    cipherText = Convert.ToBase64String(cipherBytes);
                }
                cryptor.Clear();
            }
            return cipherText;

        }



        public static string DecryptParams(string resVal)
        {
            var data = Convert.FromBase64String(resVal);
            byte[] cipherBytes = new byte[data.Length];
            string plainText = "";

            using (var crypto = CreateCryptor())
            {


                ICryptoTransform Dec = crypto.CreateDecryptor();
                using (MemoryStream ms = new MemoryStream())
                {
                    using (var cs = new CryptoStream(ms, Dec, CryptoStreamMode.Write))
                    {
                        cs.Write(cipherBytes, 0, cipherBytes.Length);
                        plainText = Encoding.Unicode.GetString(ms.ToArray());
                    }
                }
                crypto.Clear();
            }

            return plainText;
        }

Ответы [ 2 ]

2 голосов
/ 03 апреля 2020

ОБНОВЛЕНИЕ 1:

Пожалуйста, настройте IV самостоятельно, чтобы успешно расшифровать, как указывал @ maarten-bodewes. Я пропустил эту часть, и расшифровка как-то сработала (?) С вашим существующим кодом, но вы всегда должны предоставлять один и тот же ключ и IV для алгоритма шифрования симметрии c, чтобы он работал в обоих направлениях.

ОРИГИНАЛЬНЫЙ ОТВЕТ :

Ваша расшифровка завершается неудачно (выдает неверные результаты), потому что вы неправильно внедрили часть дешифрования (используя CryptoStreamMode.Write вместо CryptoStreamMode.Read) и помимо подачи в поток дешифрования всех нулевых байтов

At точка выполнения

cs.Write(cipherBytes, 0, cipherBytes.Length);

, переменная cipherBytes равна нулю. Настоящий зашифрованный буфер находится в переменной data, которую вы используете только для установки длины cipherBytes

Так что измените свой метод дешифрования на этот.

БОНУС : После исправления части дешифрования вы можете указать заполнение при sh! Я проверил с PKCS7, и это нормально.

public static string DecryptParams(string resVal)
{
    var cipherBytes = Convert.FromBase64String(resVal);
    string plainText = "";

    using (var crypto = CreateCryptor())
    {
        ICryptoTransform Dec = crypto.CreateDecryptor();
        using (MemoryStream ms = new MemoryStream(cipherBytes))
        {
            using (var cs = new CryptoStream(ms, Dec, CryptoStreamMode.Read))
            {
                byte[] decryptBlock = new byte[4096];
                MemoryStream decryptStream = new MemoryStream();
                int readBytes;
                while ((readBytes = cs.Read(decryptBlock, 0, 4096)) > 0)
                {
                    decryptStream.Write(decryptBlock, 0, readBytes);
                }
                plainText = Encoding.Unicode.GetString(decryptStream.ToArray());
            }
        }
        crypto.Clear();
    }

    return plainText;
}

Надеюсь, это поможет.

0 голосов
/ 03 апреля 2020

Благодаря Огузу

Ниже мой метод описания после редактирования

public static string DecryptParams(string resVal)
        {
            var data = Convert.FromBase64String(resVal);
            byte[] cipherBytes = new byte[data.Length];
            string plainText = "";

            using (var crypto = CreateCryptor())
            {  
                ICryptoTransform Dec = crypto.CreateDecryptor();
                using (MemoryStream ms = new MemoryStream(data))
                {
                    using (var cs = new CryptoStream(ms, Dec, CryptoStreamMode.Read))
                    {
                        cs.Read(cipherBytes, 0, cipherBytes.Length);
                        plainText = Encoding.Unicode.GetString(cipherBytes.ToArray());
                    }
                }
                crypto.Clear();
            }

            return plainText;
        }

еще одна вещь о возвращаемом результате после расшифровки я получил исходную строку плюс \ 0 \ 0 \ 0 \ 0, поэтому я использую myString.TrimEnd ('\ 0') для решения этой проблемы.

...