Почему код шифрования Rijndael не работает для больших файлов? - PullRequest
3 голосов
/ 01 октября 2011

Я использую следующий код Rijndael для шифрования много раз. Но почему он не может зашифровать файл ISO с 4,2 ГБ? На самом деле мой компьютер имеет 16 ГБ памяти, и это не должно быть проблемой памяти. Я использую Windows 7 Ultimate. Код скомпилирован как winform (.Net 4) с использованием Visual Studio 2010 (проект VB.NET).

Я проверил, что файл ISO в порядке и может быть смонтирован как виртуальный диск и даже может быть записан на DVD-диск. Так что это не проблема файла ISO.

Мой вопрос: почему следующий код не может зашифровать файл ISO размером 4,2 ГБ? Это вызвано ограничением реализации Windows / .NET 4?

Private Sub DecryptData(inName As String, outName As String, rijnKey() As Byte, rijnIV() As Byte)

    'Create the file streams to handle the input and output files.
    Dim fin As New IO.FileStream(inName, System.IO.FileMode.Open, System.IO.FileAccess.Read)
    Dim fout As New IO.FileStream(outName, System.IO.FileMode.OpenOrCreate,
       System.IO.FileAccess.Write)
    fout.SetLength(0)

    'Create variables to help with read and write.
    Dim bin(100) As Byte 'This is intermediate storage for the encryption.
    Dim rdlen As Long = 0 'This is the total number of bytes written.
    Dim totlen As Long = fin.Length 'Total length of the input file.
    Dim len As Integer 'This is the number of bytes to be written at a time.

    'Creates the default implementation, which is RijndaelManaged.
    Dim rijn As New Security.Cryptography.RijndaelManaged
    Dim encStream As New Security.Cryptography.CryptoStream(fout,
       rijn.CreateDecryptor(rijnKey, rijnIV), Security.Cryptography.CryptoStreamMode.Write)

    'Read from the input file, then encrypt and write to the output file.
    While rdlen < totlen
        len = fin.Read(bin, 0, 100)
        encStream.Write(bin, 0, len)
        rdlen = Convert.ToInt32(rdlen + len)
    End While

    encStream.Close()
    fout.Close()
    fin.Close()
End Sub

Ответы [ 2 ]

9 голосов
/ 01 октября 2011
rdlen = Convert.ToInt32(rdlen + len)

Int32 может представлять целые числа со знаком, значения которых варьируются от отрицательных 2 147 483 648 до положительных 2 147 483 647, и, поскольку 4,2 ГБ примерно вдвое больше, я думаю, rdlen никогда не будет больше totlen, и, таким образом, вы сами бесконечный цикл.

Если VB.NET работает как-то вроде C # (и я подозреваю, что так и есть), вы просто удаляете конвертирование

rdlen = rdlen + len

Результатом Long + Int будет Long. Где Long - 64-битное целое число со знаком, а Int - 32-битное целое число со знаком.

2 голосов
/ 01 октября 2011

Попробуйте изменить это:

rdlen = Convert.ToInt32(rdlen + len)

к этому:

rdlen = Convert.ToInt64(rdlen + len)
...