0

こんにちは私はファイル(任意のタイプ)からバイトを読み取り、それらをファイルに出力する暗号化アルゴリズムを実行しています。問題は、私の暗号化プログラムは16バイトのブロックしか使用しないため、ファイルが大きい場合は16のブロックに分割する必要があるか、問題が発生するたびにファイルから16バイトを読み取る方法がある場合です。

アルゴリズムは、16バイトのハードコードされた入力で正常に機能しています。暗号化された結果は、後で同じ方法で解読する必要があるため、リストまたは配列に保存する必要があります。すべてのプログラムを投稿することはできませんが、これまでのところメインで行っていることで、結果を得ることができません。

static void Main(String[] args)
{
    byte[] bytes = File.ReadAllBytes("path to file");
    var stream = new StreamReader(new MemoryStream(bytes));
    byte[] cipherText = new byte[16];
    byte[] decipheredText = new byte[16];

    Console.WriteLine("\nThe message is: ");
    Console.WriteLine(stream.ReadToEnd());

    AES a = new AES(keyInput);
    var list1 = new List<byte[]>();
    for (int i = 0; i < bytes.Length; i+=16)
    {
        a.Cipher(bytes, cipherText);
        list1.Add(cipherText);
    }

    Console.WriteLine("\nThe resulting ciphertext is: ");
    foreach (byte[] b in list1)
    {       
        ToBytes(b);
    }
}

私のループは常にバイト配列の最初の16バイトを追加することを知っていますが、私は多くの方法を試しましたが、何も機能しませんでした。バイト配列にインデックスを付けたり、アイテムをのような一時変数にコピーしたりすることはできませんtemp = bytes[i]。ToBytesメソッドは関係ありません。要素をバイトとして出力するだけです。

4

3 に答える 3

1

一度に少ししか処理できない場合は、混乱全体をメモリに読み込む必要はありません...

var filename = @"c:\temp\foo.bin";
using(var fileStream = new FileStream(filename, FileMode.Open))
{
    var buffer = new byte[16];
    var bytesRead = 0;
    while((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0)
    {
        // do whatever you need to with the next 16-byte block
        Console.WriteLine("Read {0} bytes: {1}", 
                bytesRead, 
                string.Join(",", buffer));
    }
}
于 2013-01-25T19:10:15.517 に答える
1

Cipher()メソッドのインターフェイスを変更することをお勧めします。配列全体を渡すのではなく、ソース配列と宛先配列を渡し、オフセットをブロックごとに暗号化することをお勧めします。

擬似コードは以下のとおりです。

void Cipher(byte[] source, int srcOffset, byte[] dest, int destOffset)
{
    // Cipher these bytes from (source + offset) to (source + offset + 16),
    // write the cipher to (dest + offset) to (dest + offset + 16)
    // Also I'd recommend to check that the source and dest Length is less equal to (offset + 16)!
}

使用法:

  1. 小さなファイルの場合(宛先バッファー用の1つのメモリー割り当て、ブロックごとの暗号化):

    // You can allocate the entire destination buffer before encryption!
    byte[] sourceBuffer = File.ReadAllBytes("path to file");
    byte[] destBuffer = new byte[sourceBuffer.Length];
    
    // Encrypt each block.
    for (int offset = 0; i < sourceBuffer.Length; offset += 16)
    {
        Cipher(sourceBuffer, offset, destBuffer, offset);
    }
    

    したがって、このアプローチの主な利点は、追加のメモリ割り当てを制限することです。つまり、宛先アレイが一度に割り当てられます。コピーメモリ操作もありません。

  2. 任意のサイズのファイル(ストリーム、ブロックごとの暗号化)の場合:

        byte[] inputBlock = new byte[16];
        byte[] outputBlock = new byte[16];
        using (var inputStream = File.OpenRead("input path"))
        using (var outputStream = File.Create("output path"))
        {
            int bytesRead;
            while ((bytesRead = inputStream.Read(inputBlock, 0, inputBlock.Length)) > 0)
            {
                if (bytesRead < 16)
                {
                    // Throw or use padding technique.
                    throw new InvalidOperationException("Read block size is not equal to 16 bytes");
    
                    // Fill the remaining bytes of input block with some bytes.
                    // This operation for last block is called "padding".
                    // See http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Padding
                }
    
                Cipher(inputBlock, 0, outputBlock, 0);
                outputStream.Write(outputBlock, 0, outputBlock.Length);
            }
        }
    
于 2013-01-25T19:11:05.527 に答える
0

Array.Copyを使用できます

byte[] temp = new byte[16];
Array.Copy(bytes, i, temp, 0, 16);
于 2013-01-25T19:04:56.223 に答える