私は C# と暗号化にまったく慣れていないので、しばらくお待ちください。いくつかのバイナリ データ (「オブジェクト」 - 実際にはほとんどがオブジェクトの一部のみであるため、シリアライゼーション、BinaryWriter などを使用できない/使用しない) を保存し、それをメモリに暗号化してから FileStream を使用して書き込みたい. 最初はある種の Xor を使用したいと思っていましたが、簡単に破ることができるとは知らなかったので、コードを変更して Aes を使用するようにしました。
問題は、比較的大きなファイルがいくつかあり、多くの場合、32 バイトのデータを変更または読み取るだけでよいということです。したがって、データの 1 つのチャンクのみを暗号化でき、必要なデータのチャンクのみを復号化できなければなりません。今のところ、次の解決策しか思いつきませんでした。
データを保存するときは、すべてのデータをループし、ループ内でデータのチャンクを暗号化してファイルに書き込みます。読み取り中に、データのチャンクを読み取るループがあり、ループ内で復号化を宣言する必要がありますが、これは非常に非効率的です。
暗号化と保存のコードは次のとおりです。
//setup file stream for saving data
FileStream fStream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read, 1024, false);
//setup encryption (AES)
SymmetricAlgorithm aes = Aes.Create();
byte[] key = { 145, 12, 32, 245, 98, 132, 98, 214, 6, 77, 131, 44, 221, 3, 9, 50 };
byte[] iv = { 15, 122, 132, 5, 93, 198, 44, 31, 9, 39, 241, 49, 250, 188, 80, 7 };
aes.Padding = PaddingMode.None;
ICryptoTransform encryptor = aes.CreateEncryptor(key, iv);
foreach(....)
{
//data manipulation
//encryption
MemoryStream m = new MemoryStream();
using (Stream c = new CryptoStream(m, encryptor, CryptoStreamMode.Write))
c.Write(data, 0, data.Length);
byte[] original = new byte[32];
original = m.ToArray();
fStream.Write(original, 0, original.Length);
}
キーと iv は、デバッグと問題解決を容易にするためにハードコーディングされています。これが機能するようになったら、キーと iv の生成方法を変更します。
読み取りと復号化のコードは次のとおりです。 FileStream fStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, false);
//setup encryption (AES)
SymmetricAlgorithm aes = Aes.Create();
byte[] key = { 145, 12, 32, 245, 98, 132, 98, 214, 6, 77, 131, 44, 221, 3, 9, 50 };
byte[] iv = { 15, 122, 132, 5, 93, 198, 44, 31, 9, 39, 241, 49, 250, 188, 80, 7 };
aes.Padding = PaddingMode.None;
//reading
while (numBytesToRead > 0)
{
byte[] original = new byte[32];
byte[] data = new byte[32];
int len = fStream.Read(original, 0, 32);
//error checking ...
//decryption
ICryptoTransform decryptor = aes.CreateDecryptor(key, iv); //this is a slow operation
MemoryStream m = new MemoryStream();
using (Stream c = new CryptoStream(m, decryptor, CryptoStreamMode.Write))
c.Write(original, 0, original.Length);
data = m.ToArray();
//data manipulation ...
}
問題は、ループ内でデクリプタを作成するのは非常に非効率的であるということです。かなりのデータ量になります。ループに入る前に作成すると、適切に復号化できず、暗号化を変更する必要があります (ループの前に暗号化ストリームとメモリ ストリームを宣言します) が、必要なデータのチャンクのみを暗号化/復号化することはできません。また、ランダムな読み取り/書き込みのみを必要とするファイルは多くありません。たとえば、一部のファイルでは、特定の位置からファイルの最後まで読み取りたい場合がありますが、これは非常に多くなる可能性があります。
これについてどう思いますか。これを達成するためのより良い方法はありますか?暗号化アルゴリズムが異なる可能性があります(最初はある種のxorを使用したかったのですが、「クラック」するのは非常に簡単であることがわかりました)?
psメモリ内で暗号化したいので、シーク可能なストリームを使用する必要があります。