L'imbottitura non è valida e non può essere rimossa?


126

Ho cercato online il significato di questa eccezione in relazione al mio programma ma non riesco a trovare una soluzione o il motivo per cui sta accadendo al mio programma specifico. Ho utilizzato l'esempio fornito dal mio msdn per crittografare e decrittografare un XmlDocument utilizzando l'algoritmo Rijndael. La crittografia funziona bene ma quando provo a decrittografare, ottengo la seguente eccezione:

Il riempimento non è valido e non può essere rimosso

Qualcuno può dirmi cosa posso fare per risolvere questo problema? Il mio codice qui sotto è dove ottengo la chiave e altri dati. Se cryptoMode è false, chiamerà il metodo decrypt, che è dove si verifica l'eccezione:

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
Puoi provarlo impostando esplicitamente la modalità di riempimento in modo che sia identica sia sulla crittografia che sulla decrittografia in modo che siano indentiche. Ad esempio: alg.Padding = PaddingMode.NONE;
NetSquirrel

Che aspetto ha il metodo Encrypt ()?
csharptest.net

1
Grazie ragazzi che hanno funzionato.
Brown Love

2
@NetSquirrel: grazie per il promemoria per PaddingMode.NONE. Mi fa uscire da questo errore (a un altro) ... Facendo AES sia in Java che in C #, e ora non so perché C # si lamenta del riempimento di Java, sebbene entrambi usino PKCS # 7
Hoàng Long

Risposte:


81

Rijndael / AES è un codice a blocchi. Crittografa i dati in blocchi a 128 bit (16 caratteri). Il riempimento crittografico viene utilizzato per assicurarsi che l'ultimo blocco del messaggio sia sempre della dimensione corretta.

Il tuo metodo di decrittografia si aspetta qualunque sia il suo riempimento predefinito e non lo trova. Come dice @NetSquirrel, è necessario impostare esplicitamente il riempimento sia per la crittografia che per la decrittografia. A meno che tu non abbia un motivo per fare diversamente, usa il riempimento PKCS # 7.


7
come impostare il padding in modo esplicito ??
Ahmad Hajjar,

7
Grazie l'ho trovato rj.Padding = PaddingMode.none; :)
Ahmad Hajjar

7
@AhmadHajjar Nessun riempimento ha implicazioni sulla sicurezza, non usarlo.
deviantfan

1
Ciao, ho impostato il riempimento in modo esplicito, ma non funziona. Non so quali passaggi ho sbagliato. Per favore aiuto. alg.Padding = PaddingMode.PKCS7;
Johnny,

21
Mi rendo conto che questo è un vecchio thread. Ma, per coloro che visitano, assicurati di svuotare il blocco finale durante la crittografia dei dati.
Markus

53

Assicurati che le chiavi che utilizzi per crittografare e decrittografare siano le stesse . Il metodo di riempimento anche se non impostato in modo esplicito dovrebbe comunque consentire una corretta decrittazione / crittografia (se non impostato saranno gli stessi). Tuttavia, se per qualche motivo utilizzi un set di chiavi diverso da quello utilizzato per la crittografia , riceverai questo errore:

Il riempimento non è valido e non può essere rimosso

Se stai usando un algoritmo per generare dinamicamente chiavi che non funzioneranno. Devono essere gli stessi sia per la crittografia che per la decrittografia. Un modo comune è che il chiamante fornisca le chiavi nel costruttore della classe dei metodi di crittografia, per evitare che il processo di crittografia / decrittografia abbia alcun ruolo nella creazione di questi elementi. Si concentra sull'attività in corso (crittografia e decrittografia dei dati) e richiede che il ive keyvenga fornito dal chiamante.


Questo suggerimento è stato molto utile, perché, a volte, le chiavi sono archiviate su app.config e dobbiamo sempre essere sicuri che le chiavi utilizzate per crittografare siano le stesse usate per decrittografare.
Mário Meyrelles

@atconway Ti dispiacerebbe dare un'occhiata alla mia domanda? Ho un problema simile ma in C ++ / CLI: stackoverflow.com/questions/57139447/…
Semplice

1
Suggerirei che nell'uso quotidiano, questa è probabilmente la ragione più probabile per cui le persone incontreranno questo errore. Soprattutto se non stai scherzando con le impostazioni di riempimento.
Dan

28

A vantaggio delle persone che effettuano ricerche, potrebbe valere la pena controllare l'input che viene decrittografato. Nel mio caso, le informazioni inviate per la decrittazione venivano (erroneamente) inserite come una stringa vuota. Ha provocato l'errore di riempimento.

Questo potrebbe riguardare la risposta di Rossum, ma ho pensato che valesse la pena menzionarlo.


Sono d'accordo, mi è capitato lo stesso, controllando l'input decriptato PRIMA di fare altri controlli. Ottenevo 1 byte in più rispetto a quello che avevo criptato ...
Andrea Antonangeli

Un filo vuoto è stato il colpevole anche per me.
dotNET

Il mio caso era che la passphrase non era impostata (sì, lo so), ma questa risposta mi ha portato nella giusta direzione.
Jim il

2
Il mio problema era che la stringa da decrittografare veniva convertita in lettere minuscole prima di tentare di decrittografarla. Ero ossessionato dal riempimento, dai codici e da tutto il resto, ma si è scoperto che era solo un input sbagliato. A volte basta fare un passo indietro!
Tom Gerken

15

Se la stessa chiave e lo stesso vettore di inizializzazione vengono utilizzati per la codifica e la decodifica, questo problema non deriva dalla decodifica dei dati ma dalla codifica dei dati.

Dopo aver chiamato il metodo Write su un oggetto CryptoStream, è necessario chiamare SEMPRE il metodo FlushFinalBlock prima del metodo Close.

La documentazione MSDN sul metodo CryptoStream.FlushFinalBlock dice:
"La chiamata del metodo Close chiamerà FlushFinalBlock ... "
https://msdn.microsoft.com/en-US/library/system.security.cryptography.cryptostream.flushfinalblock(v=vs .110) .aspx
Questo è sbagliato. La chiamata al metodo Close chiude semplicemente CryptoStream e il flusso di output.
Se non chiami FlushFinalBlock prima di Close dopo aver scritto i dati da crittografare, durante la decrittografia dei dati, una chiamata al metodo Read o CopyTo sul tuo oggetto CryptoStream genererà un'eccezione CryptographicException (messaggio: "Il riempimento non è valido e non può essere rimosso").

Questo è probabilmente vero per tutti gli algoritmi di crittografia derivati ​​da SymmetricAlgorithm (Aes, DES, RC2, Rijndael, TripleDES), anche se l'ho appena verificato per AesManaged e un MemoryStream come flusso di output.

Pertanto, se si riceve questa eccezione CryptographicException durante la decrittografia, leggere il valore della proprietà Lunghezza flusso di output dopo aver scritto i dati da crittografare, quindi chiamare FlushFinalBlock e leggere di nuovo il valore. Se è cambiato, sai che la chiamata a FlushFinalBlock NON è opzionale.

E non è necessario eseguire alcun riempimento a livello di codice o scegliere un altro valore della proprietà Padding. Il riempimento è un lavoro del metodo FlushFinalBlock.

.........

Nota aggiuntiva per Kevin:

Sì, CryptoStream chiama FlushFinalBlock prima di chiamare Close, ma è troppo tardi: quando viene chiamato il metodo CryptoStream Close, anche il flusso di output viene chiuso.

Se il tuo flusso di output è un MemoryStream, non puoi leggere i suoi dati dopo che è stato chiuso. Quindi è necessario chiamare FlushFinalBlock su CryptoStream prima di utilizzare i dati crittografati scritti su MemoryStream.

Se il tuo flusso di output è un FileStream, le cose vanno peggio perché la scrittura è bufferizzata. La conseguenza è che gli ultimi byte scritti potrebbero non essere scritti nel file se si chiude il flusso di output prima di chiamare Flush su FileStream. Quindi, prima di chiamare Close su CryptoStream, devi prima chiamare FlushFinalBlock sul tuo CryptoStream, quindi chiamare Flush sul tuo FileStream.


1
Perché dici che è sbagliato? Il codice per le Stream.Close()chiamate this.Dispose(true). Il codice per CryptoStream.Dispose(bool)è:if (disposing) { if (!this._finalBlockTransformed) { this.FlushFinalBlock(); } this._stream.Close(); }
Kevin Doyon

1
Questo ha risolto il mio problema. Stavo smaltendo correttamente il cryptoStream, ma la chiamata di smaltimento stava avvenendo "troppo tardi", proprio come dici tu. Ciò ha provocato l'errore "riempimento non valido", come descritto. Aggiungendo cryptoStream.FlushFinalBlock (), l'errore di riempimento non valido è stato risolto. Grazie!
Daniel Lambert

14

A volte servi di combattimenti, ho finalmente risolto il problema.
(Nota: utilizzo AES standard come algoritmo simmetrico. Questa risposta potrebbe non essere adatta a tutti.)

  1. Cambia la classe dell'algoritmo. Sostituisci la RijndaelManagedclasse con AESManageduna.
  2. Non impostare esplicitamente la KeySizeclasse di algoritmo, lasciali predefiniti.
    (Questo è il passaggio molto importante. Penso che ci sia un bug nella proprietà KeySize.)

Ecco un elenco che vuoi controllare quale argomento potresti aver perso:

  • Chiave
    (matrice di byte, la lunghezza deve essere esattamente una tra 16, 24, 32 byte per una dimensione chiave diversa)
  • IV
    (matrice di byte, 16 byte)
  • CipherMode
    (uno tra CBC, CFB, CTS, ECB, OFB)
  • PaddingMode
    (uno tra ANSIX923, ISO10126, Nessuno, PKCS7, Zeri)

3
L'impostazione non esplicita KeySizemi ha risolto immediatamente. Oh le stranezze di .NET :-(
John

Si noti che questa sembra essere una regressione nello stesso .NET Framework. Ho un codice che funzionava con RijndaelManaged, ma ha smesso di funzionare e semplicemente cambiandolo in AesManaged / AesCryptoServiceProvider, funziona di nuovo. Non avevo nemmeno alcun codice che impostasse esplicitamente KeySize. Quindi, se sei morso da questo, sentiti meglio: la colpa potrebbe non essere tua, ma del .NET Framework stesso.
Usas

6

Il mio problema era che la passPhrase della crittografia non corrispondeva alla passPhrase della decrittografia ... quindi ha generato questo errore ... un po 'fuorviante.


In realtà è vero che usiamo PaddingMode.PKCS7 per Encrypt e Decrypt ma ho ricevuto lo stesso messaggio di errore. Inoltre abbiamo ambienti Stage e Dev con valori chiave diversi. Quando ho usato la chiave appropriata, specifica per l'ambiente, questa eccezione è stata risolta ...
Maggiore

Sebbene tutte le risposte precedenti siano buone e devi usare lo stesso riempimento per Encrypt e Decrypt (nessuno è consigliato!) In realtà anche questa risposta può essere vera. Quando ho utilizzato la chiave -specifico dell'ambiente - corretta l'eccezione "System.Security.Cryptography.CryptographicException: Padding non è valido e non può essere rimosso." è stato risolto. Quindi sì, può essere fuorviante.
Maggiore

Se per "passPhrase" stai parlando del valore esatto da crittografare / decrittografare (non è un problema con l'utilizzo della chiave sbagliata), allora sì, questo era il mio problema. Il mio caso era che il valore crittografato originale era più lungo del campo della tabella del database consentito, quindi è stato troncato per adattarsi senza che me ne accorgessi. Quindi, durante la decrittografia del valore troncato, è stata generata questa eccezione.
David Gunderson

2

La soluzione che ha risolto il mio era che avevo inavvertitamente applicato chiavi diverse ai metodi di crittografia e decrittografia.


1

Mi sono imbattuto in questo errore durante il tentativo di passare un percorso di file non crittografato al metodo Decrypt. La soluzione era controllare se il file passato è crittografato prima di tentare di decrittografare

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

1
Sfido qualsiasi Hit and Run Coward sulla validità di questa soluzione.
Bee

+1 perché questa eccezione viene sollevata quando decifri due volte o decifri qualcosa non crittografato. Quindi ho letto questa risposta come "sei sicuro che i dati siano effettivamente crittografati?".
Gerardo Grignoli

0

Un altro scenario, sempre a vantaggio delle persone che cercano.

Per me questo errore si è verificato durante il metodo Dispose () che ha mascherato un errore precedente non correlato alla crittografia.

Una volta che l'altro componente è stato corretto, questa eccezione è stata eliminata.


3
Qual era l'errore precedente non correlato alla crittografia?
NStuke

0

Ho riscontrato questo errore di riempimento quando ho modificato manualmente le stringhe crittografate nel file (utilizzando il blocco note) perché volevo testare come si comporterà la funzione di decrittografia se il mio contenuto crittografato è stato modificato manualmente.

La soluzione per me era inserire un file

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

Come ho detto, il mio errore di riempimento era dovuto al fatto che stavo digitando manualmente sul testo decrittografato utilizzando il blocco note. Può essere che la mia risposta possa guidarti alla tua soluzione.


0

Ho avuto lo stesso errore. Nel mio caso è stato perché ho archiviato i dati crittografati in un database SQL. La tabella in cui sono archiviati i dati ha un tipo di dati binario (1000). Quando recupera i dati dal database, decrittografa questi 1000 byte, mentre in realtà erano 400 byte. Quindi rimuovendo gli zero finali (600) dal risultato ha risolto il problema.


0

Ho riscontrato questo errore e stavo impostando esplicitamente la dimensione del blocco: aesManaged.BlockSize = 128;

Una volta rimosso, ha funzionato.


0

Ho avuto lo stesso problema cercando di portare un programma Go su C #. Ciò significa che molti dati sono già stati crittografati con il programma Go. Questi dati devono ora essere decrittografati con C #.

La soluzione finale era PaddingMode.Noneo meglio PaddingMode.Zeros.

I metodi crittografici in 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
    }
}

Ora, decrittografia in 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;
}

Come si spiega il problema con l'imbottitura? Poco prima della crittografia, il programma Go controlla il riempimento:

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

La parte importante è questa:

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

Viene creato un nuovo array con una lunghezza appropriata, in modo che la lunghezza sia un multiplo della dimensione del blocco. Questo nuovo array è pieno di zeri. Il metodo di copia quindi copia i dati esistenti al suo interno. È garantito che il nuovo array sia più grande dei dati esistenti. Di conseguenza, ci sono zeri alla fine della matrice.

Pertanto, il codice C # può usare PaddingMode.Zeros. L'alternativa PaddingMode.Noneignora semplicemente qualsiasi imbottitura, che funziona anche. Spero che questa risposta sia utile per chiunque debba trasferire il codice da Go a C #, ecc.


0

Mi è stato segnalato lo stesso errore dal cliente. Personalmente non posso riprodurlo. Guardando il codice dei metodi Encrypt e Decrypt , entrambi hanno Padding impostato su PaddingMode.PKCS7 . Decrypt assomiglia a questo e non riesco a vedere il problema con esso rispetto a " FlushFinalBlock ". Qualcuno potrebbe far luce su di esso?

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

Ho avuto lo stesso errore. Nel mio caso la password fornita è maggiore di 16 significa che è crittografata, ma durante la decrittografia ricevo questo errore. crittografia:

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;

                    }
                }

decrittazione:

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

Ciao @sundarraj, è una domanda?
Tiago Martins Peres 李大仁
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.