sto cercando di cifrare e decifrare un flusso di file su un socket utilizzando RijndaelManaged, ma continuo a sbattere contro l'eccezioneLunghezza dei dati per decriptare è valido
CryptographicException: Length of the data to decrypt is invalid. at System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount) at System.Security.Cryptography.CryptoStream.FlushFinalBlock() at System.Security.Cryptography.CryptoStream.Dispose(Boolean disposing)
L'eccezione viene generata al termine della l'istruzione using in receiveFile, quando l'intero file è stato trasferito.
Ho provato a cercare sul Web, ma ho trovato solo le risposte ai problemi che sorgono quando si utilizza la codifica durante la crittografia e la decrittografia di una singola stringa. Io uso un FileStream, quindi non specificare alcuna codifica da utilizzare, quindi non dovrebbe essere il problema. Questi sono i miei metodi:
private void transferFile(FileInfo file, long position, long readBytes)
{
// transfer on socket stream
Stream stream = new FileStream(file.FullName, FileMode.Open);
if (position > 0)
{
stream.Seek(position, SeekOrigin.Begin);
}
// if this should be encrypted, wrap the encryptor stream
if (UseCipher)
{
stream = new CryptoStream(stream, streamEncryptor, CryptoStreamMode.Read);
}
using (stream)
{
int read;
byte[] array = new byte[8096];
while ((read = stream.Read(array, 0, array.Length)) > 0)
{
streamSocket.Send(array, 0, read, SocketFlags.None);
position += read;
}
}
}
private void receiveFile(FileInfo transferFile)
{
byte[] array = new byte[8096];
// receive file
Stream stream = new FileStream(transferFile.FullName, FileMode.Append);
if (UseCipher)
{
stream = new CryptoStream(stream, streamDecryptor, CryptoStreamMode.Write);
}
using (stream)
{
long position = new FileInfo(transferFile.Path).Length;
while (position < transferFile.Length)
{
int maxRead = Math.Min(array.Length, (int)(transferFile.Length - position));
int read = position < array.Length
? streamSocket.Receive(array, maxRead, SocketFlags.None)
: streamSocket.Receive(array, SocketFlags.None);
stream.Write(array, 0, read);
position += read;
}
}
}
Questo è il metodo che utilizzo per impostare i codici. byte [] init è un array di byte generato.
private void setupStreamCipher(byte[] init)
{
RijndaelManaged cipher = new RijndaelManaged();
cipher.KeySize = cipher.BlockSize = 256; // bit size
cipher.Mode = CipherMode.ECB;
cipher.Padding = PaddingMode.ISO10126;
byte[] keyBytes = new byte[32];
byte[] ivBytes = new byte[32];
Array.Copy(init, keyBytes, 32);
Array.Copy(init, 32, ivBytes, 0, 32);
streamEncryptor = cipher.CreateEncryptor(keyBytes, ivBytes);
streamDecryptor = cipher.CreateDecryptor(keyBytes, ivBytes);
}
Qualcuno ha un'idea in quello che potrei fare male?
Il FlushFinalBlock() viene chiamato nella sezione "chiusura" della istruzione using
cambierò il CipherMode, ho appena entrato come un esempio in modo da sapere che io non inizializzare la mia cifra in qualsiasi modo "strano". I readBytes in sendFile() non sono ancora stati utilizzati, ho dimenticato di rimuoverlo. Ho letto fino alla fine del file, quindi questo non dovrebbe essere il problema qui. Pensavo che il si stesse prendendo cura delle imbottiture? Cosa posso cambiare per farlo funzionare? – PatrickSe il flusso di cifratura è in modalità lettura, il blocco finale andrà perso se lo smaltisci; deve effettivamente leggere la fine del file dal suo stream sorgente sottostante per produrre il blocco finale. –
In risposta a Jeffrey: Se provo a chiamare stream.FlushFinalBlock(), dice NonSupportedException: FlushFinalBlock non può essere chiamato due volte nello stesso flusso. Questo non significa che una fine del file è stata letta (e inviata)? – Patrick