7

以下のコードに問題があります。暗号化が必要な一時的な場所にファイルがあります。この関数はそのデータを暗号化し、「pathToSave」の場所に保存します。

調べてみると、ファイル全体が適切に処理されていないようです。出力にビットが欠けており、ストリーム全体で while ループが実行されていないことに関係があると思われます。

余談ですが、while ループの後で CryptStrm.Close() を呼び出そうとすると、例外が発生します。これは、ファイルを復号化しようとすると、ファイルが既に使用されているというエラーが発生することを意味します!

いつものことをすべて試してみましたが、アイブはここで同様の問題を調べました。

ありがとう

public void EncryptFile(String tempPath, String pathToSave)
    {
        try
        {
            FileStream InputFile = new FileStream(tempPath, FileMode.Open, FileAccess.Read);
            FileStream OutputFile = new FileStream(pathToSave, FileMode.Create, FileAccess.Write);

            RijndaelManaged RijCrypto = new RijndaelManaged();

            //Key
            byte[] Key = new byte[32] { ... };

            //Initialisation Vector
            byte[] IV = new byte[32] { ... };

            RijCrypto.Padding = PaddingMode.None;
            RijCrypto.KeySize = 256;
            RijCrypto.BlockSize = 256;
            RijCrypto.Key = Key;
            RijCrypto.IV = IV;

            ICryptoTransform Encryptor = RijCrypto.CreateEncryptor(Key, IV);

            CryptoStream CryptStrm = new CryptoStream(OutputFile, Encryptor, CryptoStreamMode.Write);

            int data;
            while (-1 != (data = InputFile.ReadByte()))
            {
                CryptStrm.WriteByte((byte)data);
            }
        }
        catch (Exception EncEx)
        {
            throw new Exception("Encoding Error: " + EncEx.Message);
        }
    }

編集:

私の問題は暗号化にあると仮定しました。私の復号化が原因かもしれません

        public String DecryptFile(String encryptedFilePath)
    {
        FileStream InputFile = new FileStream(encryptedFilePath, FileMode.Open, FileAccess.Read);

        RijndaelManaged RijCrypto = new RijndaelManaged();

        //Key
        byte[] Key = new byte[32] { ... };

        //Initialisation Vector
        byte[] IV = new byte[32] { ... };

        RijCrypto.Padding = PaddingMode.None;
        RijCrypto.KeySize = 256;
        RijCrypto.BlockSize = 256;
        RijCrypto.Key = Key;
        RijCrypto.IV = IV;

        ICryptoTransform Decryptor = RijCrypto.CreateDecryptor(Key, IV);

        CryptoStream CryptStrm = new CryptoStream(InputFile, Decryptor, CryptoStreamMode.Read);

        String OutputFilePath = Path.GetTempPath() + "myfile.name";
        StreamWriter OutputFile = new StreamWriter(OutputFilePath);

        OutputFile.Write(new StreamReader(CryptStrm).ReadToEnd());

        CryptStrm.Close();
        OutputFile.Close();

        return OutputFilePath;
    }
4

3 に答える 3

18

さて、ここでうまくいかないことがいくつかあります。

1. IV のサイズの設定が大きすぎます。キー サイズが 256 の場合、Rijndael の IV は 16 バイトです。それよりも多くのバイトでキーを設定しようとすると、例外が発生します。IV サイズは Block size / 8 MSDN を参照して、IV サイズが正しいように設定する必要があります。

  1. なしのパディング モードがあります。データが正確に正しいブロック サイズでない限り、問題が発生します。おそらく、パディング モードを選択する必要があります。
  2. 通常、すべてのデータがストリームに書き込まれるように暗号化する場合、暗号ストリームへの書き込みが完了したら FlushFINalBlock を呼び出す必要があります。

メモリ ストリームを使用して暗号化と復号化を示すサンプル コードを投稿しています。

var tempData = "This is the text to encrypt. It's not much, but it's all there is.";

using (var rijCrypto = new RijndaelManaged())
{
    byte[] encryptedData;
    rijCrypto.Padding = System.Security.Cryptography.PaddingMode.ISO10126;
    rijCrypto.KeySize = 256;

    using (var input = new MemoryStream(Encoding.Unicode.GetBytes(tempData)))
    using (var output = new MemoryStream())
    {
        var encryptor = rijCrypto.CreateEncryptor();

        using (var cryptStream = new CryptoStream(output, encryptor, CryptoStreamMode.Write))
        {
            var buffer = new byte[1024];
            var read = input.Read(buffer, 0, buffer.Length);
            while (read > 0)
            {
                cryptStream.Write(buffer, 0, read);
                read = input.Read(buffer, 0, buffer.Length);
            }
            cryptStream.FlushFinalBlock();
            encryptedData = output.ToArray();
        }
    }

    using (var input = new MemoryStream(encryptedData))
    using (var output = new MemoryStream())
    {
        var decryptor = rijCrypto.CreateDecryptor();
        using (var cryptStream = new CryptoStream(input, decryptor, CryptoStreamMode.Read))
        {
            var buffer = new byte[1024];
            var read = cryptStream.Read(buffer, 0, buffer.Length);
            while (read > 0)
            {
                 output.Write(buffer, 0, read);
                 read = cryptStream.Read(buffer, 0, buffer.Length);
            }
            cryptStream.Flush();
            var result = Encoding.Unicode.GetString(output.ToArray());
        }
    }
}
于 2012-03-15T17:37:09.617 に答える