0

私は次のように定義されたインターフェースを持っています:

public interface IEncryptionService
{
    Stream Encrypt(Stream cleartext);
    Stream Decrypt(Stream encrypted);
}

このインターフェイスを で実装していますが、AesCryptoServiceProvider明らかに問題があります。IV (初期化ベクトル) はインターフェイスで返されません... そのため、暗号化を再度解読したくない限り、何かを暗号化しても問題ありません。Decrypt() メソッドが機能する可能性はまったくありません。

私がやりたいことは、ストリームの先頭に IV をクリアテキストで含めてから、それに追加するCryptoStreamことです。これは、本質的には「ヘッダー」を含む暗号化されたデータであり、それを取り除いてストリームの復号化に使用できます。

それで...どうすればいいですか?CryptoStream は十分に簡単に作成できますが、これは IV を暗号化するように見えますが、これは目的に反しています。をメモリにロードしCryptoStream、IV を先頭に追加して、それを MemoryStream としてストリーミングすることもできますが、これは非常に非効率的であり、大きなストリームでは機能しなくなります。

このための優れた、安全でスケーラブルなプラクティスは何ですか?

4

1 に答える 1

1

これが私が念頭に置いていたものです。IV を MemoryStream に書き込んでから、その後に暗号を追加する方法をご覧ください。次に、復号化する場合は、最初に同じ方法で IV を取り外します。

すみません、お久しぶりです。これは機能しています。ms を toArray(); にキャストしないと、適切にスケーリングされるはずです。最後に。たとえば、FileStream に書き込みを行うと、多くのメモリはまったく必要ありません。これは、IV を先頭に追加するデモです。

    private byte[] encrypt(byte[] originalPlaintextBytes)
    {
        using (SymmetricAlgorithm algorithm = AesCryptoServiceProvider.Create())
        {
            algorithm.GenerateKey();
            algorithm.GenerateIV();
            byte[] iv = algorithm.IV;
            byte[] key = algorithm.Key;
            using (ICryptoTransform encryptor = algorithm.CreateEncryptor(key, iv))
            {
                using (MemoryStream ms = new MemoryStream())
                using (CryptoStream cs = new CryptoStream(ms, encryptor,CryptoStreamMode.Write))
                {
                    BinaryWriter bw = new BinaryWriter(ms);
                    bw.Write(iv);
                    cs.Write(originalPlaintextBytes, 0, originalPlaintextBytes.Length);
                    return ms.ToArray();
                }
            }
        }
    }

上記のコードを編集するのではなく、1 メガバイトの平文ファイルをランダムに作成するプログラム全体を次に示します。次に、それを暗号文に暗号化します。このプログラムは、動作するために 1 メガバイトのメモリを必要としないことに注意してください。完全にスケーラブルです。繰り返しますが、前と同じように、このプログラムは概念を説明するためのものであり、1 バイトより大きい readBuffer を使用するとうまくいくでしょう。しかし、私はそれを作成して、核となる答えを曖昧にしたくありませんでした. これが役立つことを願っています。まさに必要なアプローチだと思います。

using System;
using System.IO;
using System.Security.Cryptography;
using System.Windows.Forms;

namespace SO_AES
{
    public partial class Form1 : Form
    {
        Random ran = new Random();
        public Form1()
        {
            InitializeComponent();
            using (var file = File.Open("Plaintext.txt", FileMode.OpenOrCreate))
            {
                byte[] junkBytes = new byte[1000];
                for (int i = 0; i < 1000; i++)
                {
                    for (int j = 0; j < 1000; j++)
                    {
                        junkBytes[j] = (byte)ran.Next(0, 255);
                    }
                    file.Write(junkBytes, 0, junkBytes.Length);
                }
            }

            using (var plainTextFile = File.Open("Plaintext.txt", FileMode.Open))
            {
                using (var cryptoTextFile = File.Open("Crypto.txt", FileMode.OpenOrCreate))
                {
                    encrypt(plainTextFile, cryptoTextFile);
                }
            }
        }

        void encrypt(Stream inStream, Stream outStream)
        {
            using (SymmetricAlgorithm algorithm = AesCryptoServiceProvider.Create())
            {
                algorithm.GenerateKey();
                algorithm.GenerateIV();
                byte[] iv = algorithm.IV;
                byte[] key = algorithm.Key;
                using (ICryptoTransform encryptor = algorithm.CreateEncryptor(key, iv))
                {
                    using (CryptoStream cs = new CryptoStream(outStream, encryptor, CryptoStreamMode.Write))
                    {
                        BinaryWriter bw = new BinaryWriter(outStream);
                        bw.Write(iv);
                        byte[] readBuffer = new byte[1];
                        BinaryReader br = new BinaryReader(inStream);
                        while (br.Read(readBuffer, 0, readBuffer.Length) != 0)
                        {
                            cs.Write(readBuffer, 0, 1);
                        }
                    }
                }
            }
            inStream.Close();
            outStream.Close();
        }
    }
}
于 2015-08-30T23:42:11.553 に答える