パディングは無効で削除できませんか?


125

私のプログラムに関してこの例外が何を意味するかをオンラインで調べましたが、解決策やそれが私の特定のプログラムで発生している理由を見つけることができません。Rijndaelアルゴリズムを使用してXmlDocumentを暗号化および復号化するために私のmsdnに提供されている例を使用しています。暗号化は正常に機能しますが、復号化しようとすると、次の例外が発生します。

パディングは無効であり、削除できません

この問題を解決するために何ができるか誰にも教えてもらえますか?以下のコードは、キーとその他のデータを取得する場所です。cryptoModeがfalseの場合は、decryptメソッドが呼び出され、例外が発生します。

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 2011

Encrypt()メソッドはどのように見えますか?
csharptest.net 2011

1
働いてくれた皆さん、ありがとう。
ブラウンラブ

2
@NetSquirrel:PaddingMode.NONEのリマインダーをありがとう。それは、C#はJavaのパディング文句を言う理由を知らない今の両方のJavaとC#でAESをやって...(他の1に)このエラーの私を取得し、両方の使用PKCS#7ものの
ホアンロング

回答:


81

Rijndael / AESはブロック暗号です。128ビット(16文字)ブロックでデータを暗号化します。 暗号パディングは、メッセージの最後のブロックが常に正しいサイズであることを確認するために使用されます。

復号化メソッドは、デフォルトのパディングが何であるかを予期しており、それを見つけていません。@NetSquirrelが言うように、暗号化と復号化の両方のパディングを明示的に設定する必要があります。特に理由がない限り、PKCS#7パディングを使用してください。


7
埋め込みを明示的に設定する方法?
Ahmad Hajjar 2012年

7
ありがとうございます。rj.Padding= PaddingMode.none; :)
Ahmad Hajjar 2012年

7
@AhmadHajjarパディングはセキュリティに影響を与えないため、使用しないでください。
deviantfan 2015年

1
こんにちは、私は明示的にパディングを設定しましたが、機能しません。どのステップを間違えたかわかりません。助けてください。alg.Padding = PaddingMode.PKCS7;
ジョニー

21
これは古いスレッドだと思います。しかし、訪問する人のために、データを暗号化するときは必ず最終ブロックをフラッシュしてください。
Markus

52

あなたが使用するキーことを確認します暗号化復号化がされている同じ。明示的に設定されていなくても、パディング方法は適切な復号化/暗号化を可能にする必要があります(設定されない場合、それらは同じになります)。ただし、何らかの理由で、暗号化に使用したものとは異なるキーのセットを復号化に使用している場合、次のエラーが発生します。

パディングは無効であり、削除できません

何らかのアルゴリズムを使用して、機能しないキーを動的に生成する場合。暗号化と復号化の両方で同じである必要があります。一般的な方法の1つは、暗号化/復号化プロセスがこれらのアイテムの作成に関与しないように、呼び出し元に暗号化メソッドクラスのコンストラクターでキーを提供させることです。これは、手元のタスク(データの暗号化と復号化)に焦点を当てており、およびが呼び出し元によって提供されることを必要ivkeyします。


キーがapp.configに保存されることがあり、暗号化に使用されるキーが復号化に使用されるキーと同じであることを常に確認する必要があるため、このヒントは非常に役に立ちました。
マリオMeyrelles

@atconway私の質問を見てみませんか?私は同様の問題を持っていますが、C ++ / CLIで:stackoverflow.com/questions/57139447/...
シンプル

日常の使用では、これがおそらくこのエラーが発生する最も可能性の高い理由です。特にパディング設定をいじっていない場合。
ダン

28

検索する人々の利益のために、解読されている入力をチェックすることは価値があるかもしれません。私の場合、復号化のために送信される情報は、(誤って)空の文字列として送信されていました。パディングエラーが発生しました。

これはロッサムの答えに関連しているかもしれませんが、言及する価値があると思いました。


私も同じように、他のチェックを行う前に、解読される入力をチェックすることに同意します。暗号化したものより1バイト多く取得していました...
Andrea Antonangeli 2014

空の文字列も私にとって犯人でした。
dotNET、2015

私の場合、パスフレーズが設定されていなかった(そうですね)が、この答えで正しい方向に進んだ。
ジム

2
私の問題は、解読しようとする前に、解読される文字列が小文字に変換されていたことでした。私はパディングと暗号などすべてにこだわっていましたが、それは単に悪い入力であることがわかりました。時々、あなたは一歩下がる必要があるだけです!
Tom Gerken 2017年

15

同じキーと初期化ベクトルがエンコードとデコードに使用されている場合、この問題はデータのデコードではなく、データのエンコードに起因します。

CryptoStreamオブジェクトでWriteメソッドを呼び出した後は、Closeメソッドの前に必ずFlushFinalBlockメソッドを呼び出す必要があります。

CryptoStream.FlushFinalBlockメソッドに関するMSDNドキュメントには次のように書かれています:
Closeメソッドを呼び出すとFlushFinalBlockが呼び出されます...
https://msdn.microsoft.com/en-US/library/system.security.cryptography.cryptostream.flushfinalblock(v=vs .110).aspx
これは誤りです。Closeメソッドを呼び出すと、CryptoStreamと出力Streamが閉じられるだけです。
暗号化するデータを書き込んだ後、閉じる前にFlushFinalBlockを呼び出さない場合、データを復号化するときに、CryptoStreamオブジェクトのReadメソッドまたはCopyToメソッドを呼び出すと、CryptographicException例外が発生します(メッセージ:「パディングが無効で削除できない」)。

これは、SymmetricAlgorithmから派生したすべての暗号化アルゴリズム(Aes、DES、RC2、Rijndael、TripleDES)に当てはまる可能性がありますが、出力ストリームとしてのAesManagedとMemoryStreamについては検証済みです。

したがって、暗号化解除時にこのCryptographicException例外を受け取った場合は、暗号化するデータを書き込んだ後に出力のStream Lengthプロパティ値を読み取り、FlushFinalBlockを呼び出してその値を再度読み取ります。変更されている場合、FlushFinalBlockの呼び出しはオプションではないことがわかります。

また、プログラムでパディングを実行したり、別のPaddingプロパティ値を選択したりする必要はありません。パディングはFlushFinalBlockメソッドジョブです。

.........

ケビンに関する補足:

はい、CryptoStreamはCloseを呼び出す前にFlushFinalBlockを呼び出しますが、遅すぎます。CryptoStreamCloseメソッドが呼び出されると、出力ストリームも閉じられます。

出力ストリームがMemoryStreamの場合、閉じた後はそのデータを読み取ることができません。したがって、MemoryStreamに書き込まれた暗号化されたデータを使用する前に、CryptoStreamでFlushFinalBlockを呼び出す必要があります。

出力ストリームがFileStreamの場合、書き込みがバッファリングされるため、状況はさらに悪化します。結果として、FileStreamでFlushを呼び出す前に出力ストリームを閉じると、最後に書き込まれたバイトがファイルに書き込まれない可能性があります。したがって、CryptoStreamでCloseを呼び出す前に、最初にCryptoStreamでFlushFinalBlockを呼び出し、次にFileStreamでFlushを呼び出す必要があります。


1
なぜそれが間違っていると言うのですか?Stream.Close()呼び出しのコードthis.Dispose(true)。以下のためのコードはCryptoStream.Dispose(bool)次のとおりです。if (disposing) { if (!this._finalBlockTransformed) { this.FlushFinalBlock(); } this._stream.Close(); }
ケビンDoyon

1
これで私の問題は解決しました。私はcryptoStreamを正しく破棄していましたが、あなたが言うように、破棄コールは「遅すぎて」起こりました。説明したように、これにより「無効なパディング」エラーが発生しました。cryptoStream.FlushFinalBlock()を追加することで、無効なパディングエラーが解決されました。ありがとう!
Daniel Lambert

14

戦闘のサーバルタイム、私は最終的に問題を解決しました。
(注:私は対称アルゴリズムとして標準のAESを使用しています。この答えはすべての人に適しているとは限りません。)

  1. アルゴリズムクラスを変更します。RijndaelManagedクラスをAESManaged1つに置き換えます。
  2. KeySizeアルゴリズムクラスを明示的に設定しないでください。デフォルトのままにします。
    (これは非常に重要なステップです。KeySizeプロパティにバグがあると思います。)

あなたが見逃したかもしれない引数をチェックしたいリストはここにあります:

  • キー
    (バイト配列。長さは、キーサイズが異なる場合、16、24、32バイトのいずれかでなければなりません。)
  • IV
    (バイト配列、16バイト)
  • CipherMode
    (CBC、CFB、CTS、ECB、OFBのいずれか)
  • PaddingMode
    (ANSIX923、ISO10126、なし、PKCS7、ゼロのいずれか)

3
明示的に設定しないとKeySizeすぐに修正されます。ああ.NETの癖:-(
John

これは.NET Framework自体のリグレッションのようです。以前はRijndaelManagedで機能していたコードがありますが、機能しなくなりました。コードをAesManaged / AesCryptoServiceProviderに変更するだけで、再び機能します。KeySizeを明示的に設定するコードすらありませんでした。したがって、これに噛まれた場合、気分が良くなります。障害はあなたにあるのではなく、.NET Framework自体にある可能性があります。
Usas

6

私の問題は、暗号化のpassPhraseが復号化のpassPhraseと一致しないことでした...そのため、このエラーが発生しました。


実際には、暗号化と復号化にPaddingMode.PKCS7を使用していますが、同じエラーメッセージが表示されました。また、キー値が異なるステージ環境と開発環境もあります。この例外が解決されたキー... -私は、適切-environment特定に使用する場合
主な

上記のすべての回答は適切であり、暗号化と復号化に同じパディングを使用する必要がありますが(実際には推奨されません)、この回答も当てはまります。適切な環境固有のキーを使用すると、例外「System.Security.Cryptography.CryptographicException:Padding is invalid and be not deleted。」という例外が発生します。解決されました ですから、誤解を招く可能性があります。
メジャー

「passPhrase」によって暗号化/復号化の正確な値について話している場合(間違ったキーを使用することによる問題ではない)、はい、これが私の問題でした。私の場合は、元の暗号化された値がデータベーステーブルフィールドで許可されている長さよりも長いため、気付かずに収まるように切り捨てられていました。次に、その切り捨てられた値を復号化すると、この例外がスローされました。
David Gunderson

2

私の問題を解決した解決策は、暗号化と復号化の方法に異なるキーを誤って適用してしまったことです。


1

暗号化されていないファイルパスをDecryptメソッドに渡そうとしたときにこのエラーに遭遇しました。解決策は、渡されたファイルが暗号化されているかどうかを確認してから、復号化を試みることでした。

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

1
このソリューションの有効性について、私はどんなHit and Run Cowardにも挑戦します。
有用なビー

+1。この例外は、2回復号するか、暗号化されていないものを復号すると発生します。だから私はこの答えを「データが実際に暗号化されていることを確信していますか?」と読みます。
ヘラルドグリニョーリ

0

もう一度検索する人々のために、別のシナリオを紹介します。

私にとって、このエラーは、暗号化に関係のない以前のエラーをマスクするDispose()メソッド中に発生しました。

他のコンポーネントが修正されると、この例外はなくなりました。


3
暗号化に関係のない以前のエラーは何ですか?
NStuke

0

暗号化されたコンテンツが手動で変更された場合の復号化機能の動作をテストしたいため、ファイル内の暗号化された文字列を(メモ帳を使用して)手動で編集すると、このパディングエラーが発生しました。

私のための解決策は、

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

私が言ったように、パディングエラーは、メモ帳を使用して復号化されたテキストを手動で上書きしていたためです。私の答えがあなたの解決策を導くかもしれません。


0

同じエラーが発生しました。私の場合は、SQLデータベースに暗号化されたデータを保存したためです。データが格納されるテーブルは、binary(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)

長さがブロックサイズの倍数になるように、適切な長さで新しい配列が作成されます。この新しい配列はゼロで埋められます。次に、copyメソッドは既存のデータをコピーします。新しいアレイが既存のデータよりも大きいことが保証されます。したがって、配列の最後にゼロがあります。

したがって、C#コードはを使用できますPaddingMode.Zeros。代替案PaddingMode.Noneは、パディングを無視するだけで、機能します。この回答がGoからC#などにコードを移植する必要がある人にとって役立つことを願っています。


0

クライアントから同じエラーが報告されました。個人的には再現できません。EncryptメソッドとDecryptメソッドのコードを見ると、どちらもPaddingPaddingMode.PKCS7に設定されていますDecryptはこのように見え、 ' 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、これは質問ですか?
Tiago Martins Peres李大仁
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.