Прокладка недійсна і її неможливо видалити?


126

Я шукав в Інтернеті, що означає це виняток стосовно моєї програми, але не можу знайти рішення або причину, чому це відбувається з моєю конкретною програмою. Я використовував приклад, наданий мій msdn для шифрування та розшифрування XmlDocument за допомогою алгоритму Rijndael. Шифрування працює добре, але коли я намагаюся розшифрувати, я отримую таке виняток:

Прокладка недійсна і її неможливо видалити

Хтось може сказати мені, що я можу зробити для вирішення цього питання? Мій код нижче - там, де я отримую ключові та інші дані. Якщо cryptoMode помилковий, він викличе метод дешифрування, де відбувається виняток:

public void Cryptography(XmlDocument doc, bool cryptographyMode)
{
    RijndaelManaged key = null;
    try
    {
    // Create a new Rijndael key.
    key = new RijndaelManaged();
    const string passwordBytes = "Password1234"; //password here 

    byte[] saltBytes = Encoding.UTF8.GetBytes("SaltBytes");
    Rfc2898DeriveBytes p = new Rfc2898DeriveBytes(passwordBytes, saltBytes);
    // sizes are devided by 8 because [ 1 byte = 8 bits ] 
    key.IV = p.GetBytes(key.BlockSize/8);
    key.Key = p.GetBytes(key.KeySize/8);

    if (cryptographyMode)
    {
        Ecrypt(doc, "Content", key);
    }
    else
    {
        Decrypt(doc, key);
    }

    }
    catch (Exception ex)
    {
    MessageBox.Show(ex.Message);
    }
    finally
    {
    // Clear the key.
    if (key != null)
    {
        key.Clear();
    }
    }

}

private void Decrypt(XmlDocument doc, SymmetricAlgorithm alg)
{
    // Check the arguments.  
    if (doc == null)
    throw new ArgumentNullException("Doc");
    if (alg == null)
    throw new ArgumentNullException("alg");

    // Find the EncryptedData element in the XmlDocument.
    XmlElement encryptedElement = doc.GetElementsByTagName("EncryptedData")[0] as XmlElement;

    // If the EncryptedData element was not found, throw an exception.
    if (encryptedElement == null)
    {
    throw new XmlException("The EncryptedData element was not found.");
    }


    // Create an EncryptedData object and populate it.
    EncryptedData edElement = new EncryptedData();
    edElement.LoadXml(encryptedElement);

    // Create a new EncryptedXml object.
    EncryptedXml exml = new EncryptedXml();


    // Decrypt the element using the symmetric key.
    byte[] rgbOutput = exml.DecryptData(edElement, alg); <----  I GET THE EXCEPTION HERE
    // Replace the encryptedData element with the plaintext XML element.
    exml.ReplaceData(encryptedElement, rgbOutput);

}

12
Чи можете ви спробувати, чітко встановивши режим прокладки, щоб він був однаковим як для шифрування, так і для розшифровки, щоб бути вказівним. Наприклад: alg.Padding = PaddingMode.NONE;
NetSquirrel

Як виглядає метод Encrypt ()?
csharptest.net

1
Дякую хлопцям, що працювали.
Коричневе кохання

2
@NetSquirrel: дякую за нагадування про PaddingMode.NONE. Це позбавляє мене від цієї помилки (до іншої) ... Робити AES як на Java, так і на C #, і тепер не знаю, чому C # скаржиться на прокладку Java, хоча обидва використовують PKCS № 7
Hoàng Long

Відповіді:


81

Rijndael / AES - це блокова кіфа. Він шифрує дані в 128-бітових (16 символьних) блоках. Криптографічна підкладка використовується для того, щоб переконатися, що останній блок повідомлення завжди має правильний розмір.

Ваш метод розшифровки очікує, що б там не було, і не знайти його. Як говорить @NetSquirrel, вам потрібно чітко встановити прокладку як для шифрування, так і для дешифрування. Якщо у вас немає причин зробити інше, використовуйте накладки PKCS №7.


7
як встановити прокладку явно ??
Ахмад Хаджар

7
Дякую, я знайшов це rj.Padding = PaddingMode.none; :)
Ахмад Хаджар

7
@AhmadHajjar Жодна накладка не має наслідків для безпеки, не використовуйте її.
девіантфан

1
Привіт, я встановив прокладку явно, але не працює. Я не знаю, які кроки я зробив неправильно. Будь ласка, допоможіть. alg.Padding = PaddingMode.PKCS7;
Джонні

21
Я усвідомлюю, що це стара нитка. Але для тих, хто відвідує, переконайтеся, що ви зашифруєте останній блок при шифруванні даних.
Маркус

53

Переконайтесь, що ключі, які ви використовуєте для шифрування та розшифрування , однакові . Спосіб заміщення, навіть якщо явно не встановлено, все одно повинен забезпечувати належне розшифрування / шифрування (якщо вони не встановлені, вони будуть однаковими). Однак , якщо ви з якоїсь - то причини використовують інший набір ключів для розшифровки , ніж використовуваний для шифрування ви будете отримувати цю помилку:

Прокладка недійсна і її неможливо видалити

Якщо ви використовуєте якийсь алгоритм для динамічного генерування ключів, які не працюватимуть. Вони повинні бути однаковими і для шифрування, і для дешифрування. Один поширений спосіб - дозволити абоненту надати ключі в конструкторі класу методів шифрування, щоб запобігти процесу шифрування / дешифрування будь-яку руку при створенні цих елементів. Він фокусується на заданій задачі (шифруванні та розшифровці даних) і вимагає ivі keyповинен бути наданий абонентом.


Ця порада була дуже корисною, оскільки інколи ключі зберігаються на app.config, і ми завжди повинні бути впевнені, що ключі, які використовуються для шифрування, такі ж, як і для їх розшифровки.
Mário Meyrelles

@atconway Чи не проти заглянути моє запитання? У мене є аналогічне питання, але в C ++ / CLI: stackoverflow.com/questions/57139447/…
Простий

1
Я б припустив, що при щоденному використанні це, мабуть, найвірогідніша причина того, що люди зіткнуться з цією помилкою. Особливо, якщо ви не возилися з налаштуваннями прокладки.
День

28

Для вигоди людей, які шукають, можливо, варто перевірити вхід, який розшифровується. У моєму випадку інформація, що надсилається для розшифровки, (помилково) надходила як порожній рядок. Це призвело до помилки прокладки.

Це може стосуватися відповіді Россума, але, на його думку, варто згадати.


Я погоджуюсь, трапилось і те саме, я перевіряв, чи вхід розшифровується ДО ПЕРЕД проведення інших перевірок. Я
набирав на

Винуватцем для мене стала також порожня струна.
dotNET

У моєму випадку не було встановлено парольну фразу (так, я знаю), але ця відповідь підвела мене в правильному напрямку.
Джим

2
Моя проблема полягала в тому, що рядок, яку потрібно розшифрувати, перетворюється на малі регістри, перш ніж я спробував її розшифрувати. Я був одержимий накладками та шифрами та всіма цими речами, але виявилося, що це просто поганий внесок. Іноді просто потрібно зробити крок назад!
Том Геркен

15

Якщо один і той же ключ і вектор ініціалізації використовуються для кодування та декодування, ця проблема виникає не від декодування даних, а від кодування даних.

Після того, як ви зателефонували методу Write на об’єкт CryptoStream, Ви завжди повинні викликати метод FlushFinalBlock перед методом Close.

Документація MSDN щодо методу CryptoStream.FlushFinalBlock говорить:
" Виклик методу Close викличе FlushFinalBlock ... "
https://msdn.microsoft.com/en-US/library/system.security.cryptography.cryptostream.flushfinalblock(v=vs .110) .aspx
Це неправильно. Виклик методу Close просто закриває CryptoStream і вихідний Stream.
Якщо ви не зателефонували FlushFinalBlock перед Close після того, як ви записали дані для шифрування, при розшифровці даних виклик методу Read чи CopyTo на вашому об’єкті CryptoStream призведе до винятку CryptographicException (повідомлення: "Прокладка недійсна і не може бути видалена").

Це, мабуть, справедливо для всіх алгоритмів шифрування, похідних від SymmetricAlgorithm (Aes, DES, RC2, Rijndael, TripleDES), хоча я просто переконався, що для AesManaged та MemoryStream як вихідний Stream.

Отже, якщо ви отримаєте це виняток CryptographicException при розшифровці, прочитайте значення властивості вихідного потоку довжини потоку після того, як ви записали ваші дані для шифрування, а потім зателефонуйте до FlushFinalBlock та прочитайте його значення ще раз. Якщо він змінився, ви знаєте, що дзвонити в FlushFinalBlock НЕ обов'язково.

І вам не потрібно виконувати програмне забезпечення будь-якого програмного забезпечення або вибирати інше значення властивості Padding. Накладка - це метод методу FlushFinalBlock.

.........

Додаткове зауваження щодо Кевіна:

Так, CryptoStream викликає FlushFinalBlock перед викликом Close, але це вже пізно: коли викликається метод CryptoStream Close, вихідний потік також закривається.

Якщо ваш вихідний потік є MemoryStream, ви не можете прочитати його дані після його закриття. Тому вам потрібно зателефонувати FlushFinalBlock на вашу CryptoStream, перш ніж використовувати зашифровані дані, записані на MemoryStream.

Якщо ваш вихідний потік - це FileStream, все гірше, тому що написання буферизовано. Наслідок того, що останні записані байти можуть бути записані у файл, якщо ви закриєте вихідний потік перед тим, як викликати Flush у FileStream. Тому перед тим, як зателефонувати Закрити в CryptoStream, спочатку потрібно зателефонувати FlushFinalBlock на CryptoStream, а потім викликати Flush на FileStream.


1
Чому ти кажеш, що це неправильно? Код для Stream.Close()дзвінків this.Dispose(true). Код для CryptoStream.Dispose(bool):if (disposing) { if (!this._finalBlockTransformed) { this.FlushFinalBlock(); } this._stream.Close(); }
Кевін Дойон

1
Це вирішило мою проблему. Я розряджав криптовалюту правильно, але виклик розпорядження відбувався "занадто пізно", як ви кажете. Це призвело до помилки "недійсне заміщення", як описано. Додавши cryptoStream.FlushFinalBlock (), помилка помилки заміни була усунена. Дякую!
Даніель Ламбер

14

Сервальний час боїв, я нарешті вирішив проблему.
(Примітка. Я використовую стандартний AES як симетричний алгоритм. Ця відповідь може підходити не для всіх.)

  1. Зміна класу алгоритму. Замініть RijndaelManagedклас наAESManaged один.
  2. Не чітко встановлюйте KeySizeклас алгоритму, залиште їх за замовчуванням.
    (Це дуже важливий крок. Я думаю, що у властивості KeySize є помилка.)

Ось список, який ви хочете перевірити, який аргумент ви могли пропустити:

  • Ключ
    (байтовий масив, довжина повинна бути точно одна з 16, 24, 32 байт для різного розміру ключа.)
  • IV
    (байтовий масив, 16 байт)
  • CipherMode
    (Один з CBC, CFB, CTS, ECB, OFB)
  • PaddingMode
    (один з ANSIX923, ISO10126, None, PKCS7, нулі)

3
Не чітко налаштовуючи KeySizeце для мене відразу. О химерність .NET :-(
Іван

Зауважте, що це, здається, є регресом у самій .NET Framework. У мене є код, який раніше працював з RijndaelManaged, але перестав працювати, і просто змінивши його на AesManaged / AesCryptoServiceProvider, він знову працює. У мене навіть не було жодного коду, який би прямо встановлював KeySize. Тож якщо вас це покусає, почувайтеся краще - вина може не у вас, а в самій .NET Framework.
Усас

6

Моя проблема полягала в тому, що passPhrase шифру не збігався з passPhrase дешифруваного ... так що він кинув цю помилку .. трохи оману.


Насправді це правда, ми використовуємо PaddingMode.PKCS7 для шифрування та розшифровки, але я отримав те саме повідомлення про помилку. Також у нас є середовище Stage та Dev з різними ключовими значеннями. Коли я застосував належну специфіку щодо навколишнього середовища - ключовий цей виняток було вирішено ...
Майор

Хоча всі вищевказані відповіді хороші, і ви повинні використовувати однакові підкладки для шифрування та розшифровки (жоден НЕ рекомендується!), Насправді ця відповідь також може бути правдивою. Коли я використав належну специфіку -середовища - введіть виняток "System.Security.Cryptography.CryptographicException: Прокладка недійсна і її неможливо видалити." було вирішено. Так що так, це може ввести в оману.
майор

Якщо в "passPhrase" ви говорите про точне значення для шифрування / розшифрування (не проблема з використанням неправильного ключа), то так, це була моя проблема. У моєму випадку первісне зашифроване значення було довше, ніж дозволено поле моєї таблиці баз даних, тому воно було усічене, щоб воно вмістилося, не розуміючи, Потім при розшифруванні цього усіченого значення цей виняток було кинуто.
Девід Гундерсон

2

Моє рішення було виправлено в тому, що я випадково застосував різні ключі до методів шифрування та розшифровки.


1

Я зіткнувся з цією помилкою під час спроби передати незашифрований шлях до методу Decrypt. Рішенням було перевірити, чи переданий файл зашифрований спочатку, перш ніж спробувати розшифрувати

if (Sec.IsFileEncrypted(e.File.FullName))
{
    var stream = Sec.Decrypt(e.File.FullName);
} 
else
{
    // non-encrypted scenario  
}

1
Я кидаю виклик будь-якому «Хіту і бігуницю» щодо обґрунтованості цього рішення.
корисноБеже

+1, оскільки цей виняток збільшується, коли ви розшифруєте двічі або розшифруєте щось, що не зашифроване. Тому я читаю цю відповідь як "Ви впевнені, що дані насправді зашифровані?".
Джерардо Гриньолі

0

Інший сценарій, знову на користь людей, які шукають.

Для мене ця помилка сталася під час методу Dispose (), який маскував попередню помилку, не пов’язану з шифруванням.

Як тільки інший компонент був виправлений, цей виняток пішов з життя.


3
Яка попередня помилка не стосувалася шифрування?
NStuke

0

Я зіткнувся з цією помилкою прокладки, коли я вручну редагував зашифровані рядки у файлі (використовуючи блокнот), тому що я хотів перевірити, як поводитиметься функція розшифрування, якщо мій зашифрований вміст буде змінено вручну.

Рішенням для мене було встановити

        try
            decryption stuff....
        catch
             inform decryption will not be carried out.
        end try

Як я сказав, що моя помилка прокладки була через те, що я вручну вводив текст розшифрованого тексту за допомогою блокнота. Моя відповідь, можливо, підкаже вас до вашого рішення.


0

У мене була така ж помилка. У моєму випадку це було тому, що я зберігав зашифровані дані в базі даних SQL. Таблиця, в якій зберігаються дані, має двійковий (1000) тип даних. При відновленні даних із бази даних вона б розшифрувала ці 1000 байт, а там, де насправді 400 байт. Отже, вилучивши з результату кінцевий нуль (600), він усунув проблему.


0

У мене виникла помилка і явно встановлювала розмір блоків: aesManaged.BlockSize = 128;

Як тільки я це зняв, це спрацювало.


0

У мене була така ж проблема, коли я намагався перенести програму Go на C #. Це означає, що безліч даних уже зашифровано програмою Go. Ці дані тепер слід розшифрувати за допомогою C #.

Кінцевий розчин PaddingMode.Noneабо скоріше PaddingMode.Zeros.

Криптографічні методи в Go:

import (
    "crypto/aes"
    "crypto/cipher"
    "crypto/sha1"
    "encoding/base64"
    "io/ioutil"
    "log"

    "golang.org/x/crypto/pbkdf2"
)

func decryptFile(filename string, saltBytes []byte, masterPassword []byte) (artifact string) {

    const (
        keyLength         int = 256
        rfc2898Iterations int = 6
    )

    var (
        encryptedBytesBase64 []byte // The encrypted bytes as base64 chars
        encryptedBytes       []byte // The encrypted bytes
    )

    // Load an encrypted file:
    if bytes, bytesErr := ioutil.ReadFile(filename); bytesErr != nil {
        log.Printf("[%s] There was an error while reading the encrypted file: %s\n", filename, bytesErr.Error())
        return
    } else {
        encryptedBytesBase64 = bytes
    }

    // Decode base64:
    decodedBytes := make([]byte, len(encryptedBytesBase64))
    if countDecoded, decodedErr := base64.StdEncoding.Decode(decodedBytes, encryptedBytesBase64); decodedErr != nil {
        log.Printf("[%s] An error occur while decoding base64 data: %s\n", filename, decodedErr.Error())
        return
    } else {
        encryptedBytes = decodedBytes[:countDecoded]
    }

    // Derive key and vector out of the master password and the salt cf. RFC 2898:
    keyVectorData := pbkdf2.Key(masterPassword, saltBytes, rfc2898Iterations, (keyLength/8)+aes.BlockSize, sha1.New)
    keyBytes := keyVectorData[:keyLength/8]
    vectorBytes := keyVectorData[keyLength/8:]

    // Create an AES cipher:
    if aesBlockDecrypter, aesErr := aes.NewCipher(keyBytes); aesErr != nil {
        log.Printf("[%s] Was not possible to create new AES cipher: %s\n", filename, aesErr.Error())
        return
    } else {

        // CBC mode always works in whole blocks.
        if len(encryptedBytes)%aes.BlockSize != 0 {
            log.Printf("[%s] The encrypted data's length is not a multiple of the block size.\n", filename)
            return
        }

        // Reserve memory for decrypted data. By definition (cf. AES-CBC), it must be the same lenght as the encrypted data:
        decryptedData := make([]byte, len(encryptedBytes))

        // Create the decrypter:
        aesDecrypter := cipher.NewCBCDecrypter(aesBlockDecrypter, vectorBytes)

        // Decrypt the data:
        aesDecrypter.CryptBlocks(decryptedData, encryptedBytes)

        // Cast the decrypted data to string:
        artifact = string(decryptedData)
    }

    return
}

... і ...

import (
    "crypto/aes"
    "crypto/cipher"
    "crypto/sha1"
    "encoding/base64"
    "github.com/twinj/uuid"
    "golang.org/x/crypto/pbkdf2"
    "io/ioutil"
    "log"
    "math"
    "os"
)

func encryptFile(filename, artifact string, masterPassword []byte) (status bool) {

    const (
        keyLength         int = 256
        rfc2898Iterations int = 6
    )

    status = false
    secretBytesDecrypted := []byte(artifact)

    // Create new salt:
    saltBytes := uuid.NewV4().Bytes()

    // Derive key and vector out of the master password and the salt cf. RFC 2898:
    keyVectorData := pbkdf2.Key(masterPassword, saltBytes, rfc2898Iterations, (keyLength/8)+aes.BlockSize, sha1.New)
    keyBytes := keyVectorData[:keyLength/8]
    vectorBytes := keyVectorData[keyLength/8:]

    // Create an AES cipher:
    if aesBlockEncrypter, aesErr := aes.NewCipher(keyBytes); aesErr != nil {
        log.Printf("[%s] Was not possible to create new AES cipher: %s\n", filename, aesErr.Error())
        return
    } else {

        // CBC mode always works in whole blocks.
        if len(secretBytesDecrypted)%aes.BlockSize != 0 {
            numberNecessaryBlocks := int(math.Ceil(float64(len(secretBytesDecrypted)) / float64(aes.BlockSize)))
            enhanced := make([]byte, numberNecessaryBlocks*aes.BlockSize)
            copy(enhanced, secretBytesDecrypted)
            secretBytesDecrypted = enhanced
        }

        // Reserve memory for encrypted data. By definition (cf. AES-CBC), it must be the same lenght as the plaintext data:
        encryptedData := make([]byte, len(secretBytesDecrypted))

        // Create the encrypter:
        aesEncrypter := cipher.NewCBCEncrypter(aesBlockEncrypter, vectorBytes)

        // Encrypt the data:
        aesEncrypter.CryptBlocks(encryptedData, secretBytesDecrypted)

        // Encode base64:
        encodedBytes := make([]byte, base64.StdEncoding.EncodedLen(len(encryptedData)))
        base64.StdEncoding.Encode(encodedBytes, encryptedData)

        // Allocate memory for the final file's content:
        fileContent := make([]byte, len(saltBytes))
        copy(fileContent, saltBytes)
        fileContent = append(fileContent, 10)
        fileContent = append(fileContent, encodedBytes...)

        // Write the data into a new file. This ensures, that at least the old version is healthy in case that the
        // computer hangs while writing out the file. After a successfully write operation, the old file could be
        // deleted and the new one could be renamed.
        if writeErr := ioutil.WriteFile(filename+"-update.txt", fileContent, 0644); writeErr != nil {
            log.Printf("[%s] Was not able to write out the updated file: %s\n", filename, writeErr.Error())
            return
        } else {
            if renameErr := os.Rename(filename+"-update.txt", filename); renameErr != nil {
                log.Printf("[%s] Was not able to rename the updated file: %s\n", fileContent, renameErr.Error())
            } else {
                status = true
                return
            }
        }

        return
    }
}

Тепер, дешифрування в C #:

public static string FromFile(string filename, byte[] saltBytes, string masterPassword)
{
    var iterations = 6;
    var keyLength = 256;
    var blockSize = 128;
    var result = string.Empty;
    var encryptedBytesBase64 = File.ReadAllBytes(filename);

    // bytes -> string:
    var encryptedBytesBase64String = System.Text.Encoding.UTF8.GetString(encryptedBytesBase64);

    // Decode base64:
    var encryptedBytes = Convert.FromBase64String(encryptedBytesBase64String);
    var keyVectorObj = new Rfc2898DeriveBytes(masterPassword, saltBytes.Length, iterations);
    keyVectorObj.Salt = saltBytes;
    Span<byte> keyVectorData = keyVectorObj.GetBytes(keyLength / 8 + blockSize / 8);
    var key = keyVectorData.Slice(0, keyLength / 8);
    var iv = keyVectorData.Slice(keyLength / 8);

    var aes = Aes.Create();
    aes.Padding = PaddingMode.Zeros;
    // or ... aes.Padding = PaddingMode.None;
    var decryptor = aes.CreateDecryptor(key.ToArray(), iv.ToArray());
    var decryptedString = string.Empty;

    using (var memoryStream = new MemoryStream(encryptedBytes))
    {
        using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
        {
            using (var reader = new StreamReader(cryptoStream))
            {
                decryptedString = reader.ReadToEnd();
            }
        }
    }

    return result;
}

Як можна пояснити проблему з накладкою? Незадовго перед шифруванням програма Go перевіряє прокладку:

// CBC mode always works in whole blocks.
if len(secretBytesDecrypted)%aes.BlockSize != 0 {
    numberNecessaryBlocks := int(math.Ceil(float64(len(secretBytesDecrypted)) / float64(aes.BlockSize)))
    enhanced := make([]byte, numberNecessaryBlocks*aes.BlockSize)
    copy(enhanced, secretBytesDecrypted)
    secretBytesDecrypted = enhanced
}

Важлива частина:

enhanced := make([]byte, numberNecessaryBlocks*aes.BlockSize)
copy(enhanced, secretBytesDecrypted)

Створюється новий масив з відповідною довжиною, щоб довжина була кратною розміру блоку. Цей новий масив заповнений нулями. Потім метод копіювання копіює в нього наявні дані. Переконується, що новий масив більше, ніж існуючі дані. Відповідно, в кінці масиву є нулі.

Таким чином, C # код може використовувати PaddingMode.Zeros. Альтернатива PaddingMode.Noneпросто ігнорує будь-яку прокладку, яка також працює. Я сподіваюся, що ця відповідь буде корисною для всіх, хто повинен перенести код з Go на C # тощо.


0

Мені повідомляється така ж помилка клієнта. Я особисто не можу спростувати це. Дивлячись на код методів шифрування та дешифрування , для обох параметрів Padding встановлено PaddingMode.PKCS7 . Розшифровка виглядає так, і я не можу побачити проблему з цим стосовно " FlushFinalBlock ". Чи може хтось, будь ласка, пролити на це світло?

public string Decrypt(string cipherText)
{
  if (string.IsNullOrEmpty(cipherText))
    return "";
  string result;
  Encoding byteEncoder = Encoding.Default;

  byte[] rijnKey = byteEncoder.GetBytes(Password);
  byte[] rijnIv = byteEncoder.GetBytes(InitialVector);
  RijndaelManaged rijn = new RijndaelManaged { Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 };

  using (MemoryStream msDecrypt = new MemoryStream(Convert.FromBase64String(cipherText)))
  {
    using (ICryptoTransform decryptor = rijn.CreateDecryptor(rijnKey, rijnIv))
    {
      using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
      {
                    using (StreamReader swDecrypt = new StreamReader(csDecrypt))
                    {
                        result = swDecrypt.ReadToEnd();
                    }
                }
    }
  }
  rijn.Clear();      
  return result.Replace("\0", "");
}

0

У мене була така ж помилка. У моєму випадку даний пароль більше 16 означає, що він зашифрований, але під час розшифровки я отримую цю помилку. Шифрування:

string keyString = "CDFUYP@ssw0rd123";
            var key = Encoding.UTF8.GetBytes(keyString);            
            using (var aesAlg = Aes.Create())
            {
                using (var encryptor = aesAlg.CreateEncryptor(key, aesAlg.IV))
                {
                    using (var msEncrypt = new MemoryStream())
                    {
                        using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                        using (var swEncrypt = new StreamWriter(csEncrypt))
                        {
                            swEncrypt.Write(text);
                        }                          
                        var iv = aesAlg.IV;

                        var decryptedContent = msEncrypt.ToArray();

                        var result = new byte[iv.Length + decryptedContent.Length];

                        Buffer.BlockCopy(iv, 0, result, 0, iv.Length);
                        Buffer.BlockCopy(decryptedContent, 0, result, iv.Length, decryptedContent.Length);

                        var encryptedString = Convert.ToBase64String(result);
                        var decryptedString = Decrypt(encryptedString);
                        if (decryptedString == null)
                        {
                            return null;
                        }
                        return encryptedString;

                    }
                }

Розшифровка:

 string keyString = "CDFUYP@ssw0rd123";
            var fullCipher = Convert.FromBase64String(cipherText);
            var iv = new byte[16];
            var cipher = new byte[16];
            Buffer.BlockCopy(fullCipher, 0, iv, 0, iv.Length);
            Buffer.BlockCopy(fullCipher, iv.Length, cipher, 0, iv.Length);
            var key = Encoding.UTF8.GetBytes(keyString);

            using (var aesAlg = Aes.Create())
            {
                using (var decryptor = aesAlg.CreateDecryptor(key, iv))
                {
                    string result;
                    using (var msDecrypt = new MemoryStream(cipher))
                    {
                        using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                        {
                            using (var srDecrypt = new StreamReader(csDecrypt))
                            {
                                result = srDecrypt.ReadToEnd();
                            }
                        }
                    }

                    return result;
                }
            }

Привіт @sundarraj, це питання?
Тіаго Мартінс Перес 李大仁
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.