O preenchimento é inválido e não pode ser removido?

125

Procurei online o que essa exceção significa em relação ao meu programa, mas não consigo encontrar uma solução ou o motivo pelo qual ela está acontecendo com meu programa específico. Tenho usado o exemplo fornecido por meu msdn para criptografar e descriptografar um XmlDocument usando o algoritmo Rijndael. A criptografia funciona bem, mas quando tento descriptografar, obtenho a seguinte exceção:

O preenchimento é inválido e não pode ser removido

Alguém pode me dizer o que posso fazer para resolver esse problema? Meu código abaixo é onde obtenho a chave e outros dados. Se cryptoMode for falso, ele chamará o método decrypt, que é onde ocorre a exceção:

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

}
Amor marrom
fonte
12
Você pode tentar definindo explicitamente o modo de preenchimento para ser idêntico na criptografia e descriptografia para serem idênticos. Por exemplo: alg.Padding = PaddingMode.NONE;
NetSquirrel de
Qual é a aparência do método Encrypt ()?
csharptest.net
1
Obrigado pessoal que funcionou.
Brown Love
2
@NetSquirrel: obrigado pelo lembrete para PaddingMode.NONE. Isso me tira desse erro (para outro) ... Fazendo AES em Java e C #, e agora não sei por que C # reclama do preenchimento de Java, embora ambos usem PKCS # 7
Hoàng Long,

Respostas:

81

Rijndael / AES é uma cifra de bloco. Ele criptografa dados em blocos de 128 bits (16 caracteres). O preenchimento criptográfico é usado para garantir que o último bloco da mensagem sempre tenha o tamanho correto.

Seu método de descriptografia espera o preenchimento padrão e não o encontra. Como @NetSquirrel diz, você precisa definir explicitamente o preenchimento para criptografia e descriptografia. A menos que você tenha um motivo para fazer o contrário, use o preenchimento PKCS # 7.

rossum
fonte
7
como definir o preenchimento explicitamente ??
Ahmad Hajjar
7
Obrigado, encontrei rj.Padding = PaddingMode.none; :)
Ahmad Hajjar
7
@AhmadHajjar Nenhum preenchimento tem implicações de segurança, não o use.
deviantfan
1
Olá, eu defini o preenchimento explicitamente, mas não funciona. Não sei quais passos dei errado. Por favor ajude. alg.Padding = PaddingMode.PKCS7;
Johnny
21
Eu percebo que este é um tópico antigo. Mas, para os visitantes, certifique-se de liberar o bloco final ao criptografar os dados.
Markus
52

Certifique-se de que as chaves que você usa para criptografar e descriptografar são as mesmas . O método de preenchimento, mesmo se não definido explicitamente, deve permitir a descriptografia / criptografia adequada (se não definido, eles serão os mesmos). No entanto, se você, por algum motivo, estiver usando um conjunto de chaves diferente para criptografar daquele usado para criptografar , receberá este erro:

O preenchimento é inválido e não pode ser removido

Se você estiver usando algum algoritmo para gerar chaves dinamicamente, isso não funcionará. Eles precisam ser os mesmos para criptografia e descriptografia. Uma maneira comum é fazer com que o chamador forneça as chaves no construtor da classe de métodos de criptografia, para evitar que o processo de criptografia / descriptografia tenha qualquer influência na criação desses itens. Ele se concentra na tarefa em questão (criptografar e descriptografar dados) e requer que ive keyseja fornecido pelo chamador.

atconway
fonte
Essa dica foi muito útil, pois, às vezes as chaves são armazenadas no app.config e devemos sempre ter certeza de que as chaves utilizadas para criptografar são as mesmas usadas para descriptografar.
Mário Meyrelles
@atconway Você se importaria de dar uma olhada na minha pergunta? Tenho um problema semelhante, mas em C ++ / CLI: stackoverflow.com/questions/57139447/…
Simples
Eu sugeriria que, no uso diário, esse é provavelmente o motivo mais provável para as pessoas encontrarem esse erro. Principalmente se você não estiver mexendo nas configurações de preenchimento.
Dan
28

Para o benefício das pessoas que procuram, pode valer a pena verificar a entrada que está sendo descriptografada. No meu caso, as informações enviadas para descriptografia estavam (erroneamente) entrando como uma string vazia. Isso resultou no erro de preenchimento.

Isso pode estar relacionado à resposta do rossum, mas achou que vale a pena mencionar.

HockeyJ
fonte
Concordo, aconteceu comigo o mesmo, verificando a entrada que está sendo descriptografada ANTES de fazer outras verificações. Estava recebendo 1 byte a mais do que codifiquei ...
Andrea Antonangeli
Um barbante vazio foi o culpado para mim também.
dotNET
Meu caso era que a senha não foi definida (sim, eu sei), mas essa resposta me levou à direção certa.
Jim
2
Meu problema era que a string a ser descriptografada estava sendo convertida para minúsculas antes de eu tentar descriptografá-la. Eu estava obcecado com o preenchimento e as cifras e todas essas coisas, mas descobri que era apenas uma entrada ruim. Às vezes, você só precisa dar um passo para trás!
Tom Gerken
15

Se a mesma chave e o mesmo vetor de inicialização forem usados ​​para codificação e decodificação, esse problema não virá da decodificação de dados, mas da codificação de dados.

Depois de chamar o método Write em um objeto CryptoStream, você deve SEMPRE chamar o método FlushFinalBlock antes do método Close.

A documentação do MSDN sobre o método CryptoStream.FlushFinalBlock diz:
" Chamar o método Close chamará FlushFinalBlock ... "
https://msdn.microsoft.com/en-US/library/system.security.cryptography.cryptostream.flushfinalblock(v=vs .110) .aspx
Isso está errado. Chamar o método Close apenas fecha o CryptoStream e o fluxo de saída.
Se você não chamar FlushFinalBlock antes de Close depois de gravar os dados a serem criptografados, ao descriptografar os dados, uma chamada para o método Read ou CopyTo em seu objeto CryptoStream lançará uma exceção CryptographicException (mensagem: "Preenchimento é inválido e não pode ser removido").

Isso provavelmente é verdadeiro para todos os algoritmos de criptografia derivados de SymmetricAlgorithm (Aes, DES, RC2, Rijndael, TripleDES), embora eu apenas tenha verificado isso para AesManaged e um MemoryStream como fluxo de saída.

Portanto, se você receber esta exceção CryptographicException na descriptografia, leia o valor da propriedade Stream Length de saída depois de gravar seus dados para serem criptografados e, em seguida, chame FlushFinalBlock e leia seu valor novamente. Se mudou, você sabe que chamar FlushFinalBlock NÃO é opcional.

E você não precisa executar nenhum preenchimento programaticamente ou escolher outro valor de propriedade de preenchimento. O preenchimento é um trabalho do método FlushFinalBlock.

.........

Observação adicional para Kevin:

Sim, CryptoStream chama FlushFinalBlock antes de chamar Close, mas é tarde demais: quando o método CryptoStream Close é chamado, o fluxo de saída também é fechado.

Se o fluxo de saída for um MemoryStream, você não poderá ler seus dados depois de fechado. Portanto, você precisa chamar FlushFinalBlock em seu CryptoStream antes de usar os dados criptografados gravados no MemoryStream.

Se o fluxo de saída for um FileStream, as coisas são piores porque a gravação é armazenada em buffer. A consequência é que os últimos bytes gravados podem não ser gravados no arquivo se você fechar o fluxo de saída antes de chamar Flush em FileStream. Portanto, antes de chamar Close no CryptoStream, você precisa primeiro chamar FlushFinalBlock em seu CryptoStream e, em seguida, chamar Flush em seu FileStream.

Figolu
fonte
1
Por que você diz que está errado? O código para Stream.Close()chamadas this.Dispose(true). O código para CryptoStream.Dispose(bool)é:if (disposing) { if (!this._finalBlockTransformed) { this.FlushFinalBlock(); } this._stream.Close(); }
Kevin Doyon
1
Isso resolveu meu problema. Eu estava descartando o cryptoStream corretamente, mas a chamada de descarte estava acontecendo "tarde demais", como você disse. Isso resultou no erro de "preenchimento inválido", conforme descrito. Ao adicionar cryptoStream.FlushFinalBlock (), o erro de preenchimento inválido foi resolvido. Obrigado!
Daniel Lambert
14

A tempos servais de luta, finalmente resolvi o problema.
(Observação: eu uso AES padrão como algoritmo simétrico. Esta resposta pode não ser adequada para todos.)

  1. Altere a classe do algoritmo. Substitua a RijndaelManagedclasse por AESManageduma.
  2. Não defina explicitamente a KeySizeclasse de algoritmo, deixe-os como padrão.
    (Esta é a etapa muito importante. Acho que há um bug na propriedade KeySize.)

Aqui está uma lista que você deseja verificar qual argumento você pode ter perdido:

  • Chave
    (matriz de bytes, o comprimento deve ser exatamente um de 16, 24, 32 bytes para tamanhos de chave diferentes).
  • IV
    (matriz de bytes, 16 bytes)
  • CipherMode
    (um de CBC, CFB, CTS, ECB, OFB)
  • PaddingMode
    (um de ANSIX923, ISO10126, Nenhum, PKCS7, Zeros)
Johnny
fonte
3
Não definir explicitamente KeySizecorrigiu para mim imediatamente. Ah, as peculiaridades do .NET :-(
John,
Observe que isso parece ser uma regressão no próprio .NET Framework. Eu tenho um código que costumava funcionar com RijndaelManaged, mas parou de funcionar e, simplesmente alterando para AesManaged / AesCryptoServiceProvider, ele funciona novamente. Eu nem mesmo tinha nenhum código definindo explicitamente o KeySize. Portanto, se você for mordido por isso, sinta-se melhor - a culpa pode não estar em você, mas no próprio .NET Framework.
Usas
6

Meu problema era que a senha de criptografia não correspondia à senha de descriptografia ... então gerava esse erro ... um pouco enganador.

ecklerpa
fonte
Na verdade, é verdade que usamos PaddingMode.PKCS7 para criptografar e descriptografar, mas recebi a mesma mensagem de erro. Também temos ambiente Stage e Dev com diferentes valores-chave. Quando eu usei a chave específica do ambiente, esta exceção foi resolvida ...
Grande
Embora todas as respostas acima sejam boas e você deva usar o mesmo preenchimento para Criptografar e Descriptografar (nenhum NÃO é recomendado!), Na verdade, essa resposta também pode ser verdadeira. Quando usei o apropriado - específico do ambiente - digite a exceção "System.Security.Cryptography.CryptographicException: Preenchimento é inválido e não pode ser removido." foi resolvido. Então, sim, pode ser enganoso.
Grande
Se por "senha" você está falando sobre o valor exato a criptografar / descriptografar (não é um problema com o uso da chave errada), então sim, esse foi o meu problema. Meu caso era que o valor criptografado original era maior do que o campo da tabela do banco de dados permitia, então estava sendo truncado para caber sem que eu percebesse. Então, ao descriptografar esse valor truncado, essa exceção foi lançada.
David Gunderson
2

A solução que consertou o meu foi que eu inadvertidamente apliquei chaves diferentes aos métodos de criptografia e descriptografia.

Rondakay
fonte
1

Encontrei este erro ao tentar passar um caminho de arquivo não criptografado para o método de descriptografar. A solução foi verificar se o arquivo transmitido está criptografado antes de tentar descriptografar

if (Sec.IsFileEncrypted(e.File.FullName))
{
    var stream = Sec.Decrypt(e.File.FullName);
} 
else
{
    // non-encrypted scenario  
}
útilBee
fonte
1
Eu desafio qualquer covarde Hit and Run sobre a validade desta solução.
útilBee
+1 porque essa exceção é gerada quando você descriptografa duas vezes ou descriptografa algo não criptografado. Portanto, li esta resposta como "tem certeza de que os dados estão realmente criptografados?".
Gerardo Grignoli
0

Outro cenário, novamente para o benefício das pessoas que procuram.

Para mim, esse erro ocorreu durante o método Dispose (), que mascarou um erro anterior não relacionado à criptografia.

Depois que o outro componente foi corrigido, essa exceção foi embora.

Clay Lenhart
fonte
3
Qual foi o erro anterior não relacionado à criptografia?
NStuke
0

Eu encontrei este erro de preenchimento quando eu editei manualmente as strings criptografadas no arquivo (usando o bloco de notas) porque eu queria testar como a função de descriptografia se comportaria se meu conteúdo criptografado fosse alterado manualmente.

A solução para mim foi colocar um

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

Como eu disse, meu erro de preenchimento foi porque eu estava digitando manualmente sobre o texto descriptografado usando o bloco de notas. Pode ser minha resposta pode guiá-lo para sua solução.

webzy
fonte
0

Eu tive o mesmo erro. No meu caso, foi porque armazenei os dados criptografados em um banco de dados SQL. A tabela em que os dados são armazenados tem um tipo de dados binário (1000). Ao recuperar os dados do banco de dados, ele descriptografaria esses 1000 bytes, enquanto lá estavam, na verdade, 400 bytes. Portanto, remover os zeros à direita (600) do resultado corrigiu o problema.

Martijn
fonte
0

Eu tive este erro e estava definindo explicitamente o tamanho do bloco: aesManaged.BlockSize = 128;

Depois de remover isso, funcionou.

Barry Franklin
fonte
0

Tive o mesmo problema ao tentar portar um programa Go para C #. Isso significa que muitos dados já foram criptografados com o programa Go. Esses dados agora devem ser descriptografados com C #.

A solução final foi PaddingMode.Noneou melhor PaddingMode.Zeros.

Os métodos criptográficos em 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
}

... e ...

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

Agora, descriptografia em 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;
}

Como o problema com o preenchimento pode ser explicado? Antes da criptografia, o programa Go verifica o preenchimento:

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

A parte importante é esta:

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

Uma nova matriz é criada com um comprimento apropriado, de modo que o comprimento seja um múltiplo do tamanho do bloco. Esta nova matriz é preenchida com zeros. O método de cópia então copia os dados existentes para ele. É garantido que o novo array é maior do que os dados existentes. Conseqüentemente, existem zeros no final da matriz.

Assim, o código C # pode usar PaddingMode.Zeros. A alternativa PaddingMode.Nonesimplesmente ignora qualquer preenchimento, o que também funciona. Espero que esta resposta seja útil para quem precisa portar o código Go para C #, etc.

SommerEngineering
fonte
0

Sou relatado o mesmo erro pelo cliente. Eu pessoalmente não posso reproduzi-lo. Olhando para o código dos métodos Encrypt e Decrypt , ambos têm Padding definido como PaddingMode.PKCS7 . Decifrar se parece com isso e não consigo ver o problema com ele em relação a ' FlushFinalBlock '. Alguém poderia lançar alguma luz sobre isso?

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", "");
}
Alexandre
fonte
0

Eu tive o mesmo erro. No meu caso, a senha fornecida é maior que 16 significa que ela criptografou, mas durante a descriptografia estou recebendo este erro. Criptografia:

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;

                    }
                }

Descriptografar:

 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
fonte
Olá @sundarraj, é uma pergunta?
Tiago Martins Peres 李大仁 21/12/19