Ich versuche, einen Datei-Stream über einen Socket mit RijndaelManaged zu verschlüsseln und zu entschlüsseln, aber ich immer stoßen AusnahmeLänge der Daten zu entschlüsseln, ist ungültig
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)
Die Ausnahme am Ende geworfen wird von die using-Anweisung in receiveFile, wenn die gesamte Datei übertragen wurde.
Ich habe versucht, im Internet zu suchen, aber fand nur Antworten auf Probleme, die auftreten, wenn Sie Codierung beim Verschlüsseln und Entschlüsseln einer einzelnen Zeichenfolge verwenden. Ich benutze einen FileStream, also gebe ich kein Encoding an, das verwendet werden sollte, also sollte das nicht das Problem sein. Dies sind meine Methoden:
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;
}
}
}
Dies ist die Methode, die ich verwende, um die Chiffren einzurichten. byte [] init ist ein generiertes Byte-Array.
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);
}
Wer hat eine Idee, was ich falsch machen könnte?
Die FlushFinalBlock() -Methode in der „Schließabschnitt“ der Anweisung using
ich die CipherMode ändert genannt wird, trat ich es nur als ein Beispiel, so dass Sie wissen, dass ich in jeder meine Chiffre nicht initialisieren "komischer Weg. Die readBytes in SendFile() wird noch nicht verwendet, ich habe vergessen, es zu entfernen. Ich lese bis zum Ende der Datei, also sollte das hier nicht das Thema sein. Ich dachte, kümmerte sich um die Polsterung? Was kann ich ändern, damit es funktioniert? – PatrickWenn der Verschlüsselungsstrom im Lesemodus ist, geht der letzte Block verloren, wenn Sie ihn entsorgen; Sie muss das Ende der Datei aus dem zugrunde liegenden Quelldatenstrom lesen, um den letzten Block zu erzeugen. –
Als Antwort auf Jeffrey: Wenn ich versuche, stream.FlushFinalBlock() aufzurufen, heißt es NonSupportedException: FlushFinalBlock kann nicht zweimal im selben Stream aufgerufen werden. Bedeutet das nicht, dass ein Dateiende gelesen (und gesendet) wurde? – Patrick