C#aes encryption:输入大小不是输出大小

时间:2015-02-08 12:30:27

标签: c# sockets encryption aes

我正在尝试读取文件,对其进行加密,并通过套接字将其发送到服务器,然后写入文件。然后反过来,在服务器上读取它,将其发送到客户端,解密并再次写入。

使用C#Aes类的问题是,输入大小不等于输出大小。

例如,当我从文件中读取4096个字节时,输出大小为4112个字节,多16个字节。好的,所以在服务器上发送和写入了4112个字节,但是当我再次获取文件时,我只能在套接字上发送最多4096个字节,然后,当然,客户端上的解密函数会抛出异常,填充无效,无法删除。当然,我可以尝试在客户端上读取更少的字节,但这也不行。

我是一位非常有经验的C ++程序员,我使用OpenSsl完成了这项工作,它就像一个魅力。输入大小一直是输出大小,我不知道我在C#中的函数有什么问题。

这是发送部分:

byte[]  SendData = new byte[4096];

iBytesRead = FileRead.Read (SendData, 0, 4096);

SendData = aes.encrypt (Encoding.Default.GetString (SendData, 0, iBytesRead), iBytesRead);

String a = aes.decrypt (SendData); // no problems here because the size is correct

Socket.sendB     (SendData, SendData.Length);

以及从服务器接收的部分:

byte[] WriteData = new byte[4096],
                   Temp;

if ((iBytesReceived = Socket.receiveB (ref WriteData)) == 0)
    break;

if (Encoding.ASCII.GetString (WriteData, 0, iBytesReceived) == "end")
    break;


for (uint i = 0; i < iBytesReceived; i++)
    Temp[i] = WriteData[i];

byte[] a = Encoding.Default.GetBytes (aes.decrypt (Temp));

FileWrite.Write (a, 0, Temp.Length);

Aes功能:

public byte[] encrypt(String _InStr, int _InStrLength)
    {
        if (!bKeySet)
            return ErrorReturn;

        byte[] encrypted;

        using (Aes aes = Aes.Create ())
        {
            aes.Key = Key;
            aes.IV = IV;

            //aes.Padding = PaddingMode.PKCS7;
            //aes.BlockSize = 128;
            //aes.KeySize = 128;
            //aes.Mode = CipherMode.CFB;

            ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);

            // Create the streams used for encryption. 
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter sw = new StreamWriter(cs))
                    {
                        sw.Write(_InStr);                   
                    }
                }

                ms.Close ();

                encrypted = ms.ToArray (); 
            }
        }

        return encrypted;
    }

    public String decrypt(byte[] _InStr)
    {
        if (!bKeySet)
            return "";

        String plaintext;


        using (Aes aes = Aes.Create ())
        {
            aes.Key = Key;
            aes.IV = IV;

            //aes.Padding = PaddingMode.PKCS7;
            //aes.BlockSize = 128;
            //aes.KeySize = 128;
            //aes.Mode = CipherMode.CBC;

            ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);

            // Create the streams used for decryption. 
            using (MemoryStream msDecrypt = new MemoryStream(_InStr))
            {
                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                    {
                        plaintext = srDecrypt.ReadToEnd ();
                    }
                }
            }
        }

        return plaintext;
    }

1 个答案:

答案 0 :(得分:0)

如上所述,如果使用任何填充,输出将与块大小对齐。但是,当使用PaddingMode.None时,.Net不希望使用不完整的块。您应该在加密(解密)之前自己填充数据并删除之后添加的字节。 其中一种方法是将wrap ICryptoTransform传递给CryptoStream