2011-02-16 8 views
6

No estoy seguro de qué está pasando aquí. Mi aplicación es el cifrado de archivos correctamente y sin problema, pero está lanzando una IndexOutOfRangeException cuando se trata de descifrar el mismo archivo ...Índice fuera de rango al descifrar un archivo

Aquí está mi código:

Public Sub EncryptDecrypt(ByVal Action As String, ByVal InFile As String, ByVal OutFile As String) 
    Try 
     Dim Buffer(4096) As Byte 
     Dim Stream As CryptoStream 
     Dim Rij As New System.Security.Cryptography.RijndaelManaged 
     Dim Key(), IV() As Byte 

     FSIn = New FileStream(InFile, FileMode.Open, FileAccess.Read) 
     FSOut = New FileStream(OutFile, FileMode.OpenOrCreate, FileAccess.Write) 
     FSOut.SetLength(0) 

     Key = CreateKey("p0Ju423KQY7h4D29Ml536jbX7gS2Q6Rtm87XvRttlKiZ") 
     IV = CreateIV("p0Ju423KQY7h4D29Ml536jbX7gS2Q6Rtm87XvRttlKiZ") 

     If Action = "E" Then 
      Stream = New CryptoStream(FSOut, Rij.CreateEncryptor(Key, IV), CryptoStreamMode.Write) 
     Else 
      Stream = New CryptoStream(FSOut, Rij.CreateDecryptor(Key, IV), CryptoStreamMode.Write) 
     End If 

     Stream.Close() 
     FSIn.Close() 
     FSOut.Close() 
    Catch ex As Exception 
     MsgBox(ex.ToString) 
    End Try 
End Sub 

El error aparece en la línea Stream.Close().
que han aplicado el mismo código en otro lugar y que no tiene ningún problema ...

Aquí está mi seguimiento de la pila:

System.IndexOutOfRangeException fue capturado mensaje = "Índice fuera de los límites de la matriz ".
Fuente = "mscorlib" StackTrace: en System.Security.Cryptography.RijndaelManagedTransform.DecryptData (byte [] INPUTBUFFER, Int32 inputOffset, Int32 inputCount, Byte [] & OutputBuffer, Int32 outputOffset, PaddingMode paddingMode, Boolean flast) en System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock (byte [] INPUTBUFFER, Int32 inputOffset, Int32 inputCount) en System.Security.Cryptography.CryptoStream.FlushFinalBlock() en System.Security.Cryptography.CryptoStream.Dispose (Boolean desechando) en Sys tem.IO.Stream.Close() en Crypt.EncryptDecrypt (acción de las cuerdas, cuerdas INFILE, Cadena OUTFILE) en D: \ Desarrollo \ Projects \ Web \ WebSite1 \ App_Code \ Crypt.vb: Línea 34 InnerException:

Cualquier ayuda será muy apreciada.

EDIT 1 Después del comentario de aaz, que revisó y se sustituye

Stream = New CryptoStream(FSOut, Rij.CreateDecryptor(Key, IV), CryptoStreamMode.Write) 

con

Stream = New CryptoStream(FSIn, Rij.CreateDecryptor(Key, IV), CryptoStreamMode.Write) 

aquí está el resultado Seguimiento de la pila:

System.IndexOutOfRangeException fue capturado Mensaje = "Índice w como fuera de los límites de la matriz ". Fuente = "mscorlib" StackTrace: en System.Security.Cryptography.RijndaelManagedTransform.DecryptData (Byte []> INPUTBUFFER, Int32 inputOffset, Int32 inputCount, Byte [] & OutputBuffer, Int32> outputOffset, PaddingMode paddingMode, Boolean flast) en System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock (Byte []> inputBuffer, Int32 inputOffset, Int32 inputCount) en System.Security.Cryptography.CryptoStream.FlushFinalBlock() en System.Security.Cryptography.CryptoStream.Dispose (Boolean disposing) en System.IO.Stream.Close() en Crypt.EncryptDecrypt (String Action, String InFile, String OutFile) en> D: \ Development \ Projects \ Web \ WebSite1 \ App_Code \ Crypt.VB: línea 34 InnerException:

Me parece que es el mismo error ...

FIN EDIT 1

+1

¿El código está completo? En realidad, no copia los datos de 'FSIn' a' Stream'. – aaz

+0

Esto es lo que me confunde ... Funciona sin problemas en otra aplicación donde lo he usado. Sin embargo, soy bastante nuevo en encriptación, así que estoy retocando aquí y allá. – Ortund

Respuesta

1

Bueno, creo que hay un par de cosas que necesitan ser corregidos . Por un lado, no parece que el FSOut se utilice nunca realmente ahora que ha cambiado el FSOut a FSIn. Parece que está utilizando uno u otro, pero desde la estructura del código, creo que su intención era tomar un archivo y cifrar o descifrar los datos en otro archivo.

Considere empezar desde cero utilizando http://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndael.aspx como punto de partida y si su intención es que lea de un archivo y escriba a otro modifíquelo como considere oportuno o considere tener un método auxiliar que cree una copia del archivo en la memoria, cifra el archivo, lo mueve y reemplaza el archivo en la memoria a la ubicación de inicio, hacerlo de esta manera le permite aprovechar este código para cualquier caso y realmente no incurre en demasiados gastos generales.

+0

Estás 100% correcto en lo que parezco estar haciendo. La idea es que un archivo se descifre cuando se lee o se escribe, y se cifra cuando se completa la operación de lectura/escritura. –

0

CryptoStream emite un relleno de estilo PKCS # 7 al final de los datos, que puede incluir desde un byte hasta un bloque de cifrado completo, pero nunca es de longitud cero; esto garantiza tanto que el flujo cifrado sea un múltiplo del tamaño del bloque en longitud, y que el relleno se puede eliminar sin ambigüedad. ¿Es posible que intente descifrar algo que no es información encriptada válida?

+0

No es probable ya que la línea 'Stream = New CryptoStream (FSOut, Rij.CreateEncryptor (Key, IV), CryptoStreamMode.Write)' que encripta el archivo original se ejecuta sin incidentes. –

+0

@Logan: se puede ejecutar, pero ¿cómo sabes que está funcionando correctamente? Parece que está creando un archivo vacío, lo que daría un error en el descifrado por la razón descrita por Jeffrey. – aaz

Cuestiones relacionadas