Length of the data to decrypt is invalid

随声附和 提交于 2019-11-29 03:49:48

It looks to me like you're not properly sending the final block. You need to at least FlushFinalBlock() the sending CryptoStream in order to ensure that the final block (which the receiving stream is looking for) is sent.

By the way, CipherMode.ECB is more than likely an epic fail in terms of security for what you're doing. At least use CipherMode.CBC (cipher-block chaining) which actually uses the IV and makes each block dependent on the previous one.

EDIT: Whoops, the enciphering stream is in read mode. In that case you need to make sure you read to EOF so that the CryptoStream can deal with the final block, rather than stopping after readBytes. It's probably easier to control if you run the enciphering stream in write mode.

One more note: You cannot assume that bytes in equals bytes out. Block ciphers have a fixed block size they process, and unless you are using a cipher mode that converts the block cipher to a stream cipher, there will be padding that makes the ciphertext longer than the plaintext.

After the comment made by Jeffrey Hantin, I changed some lines in receiveFile to

using (stream) {
    FileInfo finfo = new FileInfo(transferFile.Path);
    long position = finfo.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;
    }
}

->

using (stream) {
    int read = array.Length;
    while ((read = streamSocket.Receive(array, read, SocketFlags.None)) > 0) {
        stream.Write(array, 0, read);
        if ((read = streamSocket.Available) == 0) {
            break;
        }
    }
}

And voila, she works (because of the ever so kind padding that I didn't care to bother about earlier). I'm not sure what happens if Available returns 0 even though all data hasn't been transferred, but I'll tend to that later in that case. Thanks for your help Jeffrey!

Regards.

cipher.Mode = CipherMode.ECB;

Argh! Rolling your own security code is almost always a bad idea.

Mine i just removed the padding and it works

Commented this out - cipher.Padding = PaddingMode.ISO10126;

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!