Search code examples
c#.netcryptographyaes

The input data is not a complete block for CFB mode AES-128 encryption C#


I am trying to encrypt data using AES-128, CFB mode. Below code block works for dotnet 5.x target framework but gives

The input data is not a complete block

error at bw.write() for dotnet 4.7.2. Ideally it should work as CFB mode turns a block cipher into a stream cipher which doesn't need padding. I have also tried csEncrypt.Write(dataToBeEncrypted, 0, dataToBeEncrypted.Length) instead of bw.Write(). In this case it fails in next line where it converts memory stream to array with same error.

     using (AesCryptoServiceProvider Aes128 = new AesCryptoServiceProvider())
     {

        Aes128.BlockSize = 128;
        Aes128.KeySize = 128;

        //
        // Specify CFB8 mode
        //
        Aes128.Mode = CipherMode.CFB;
        Aes128.FeedbackSize = 8;
        Aes128.Padding = PaddingMode.None;
        //
        // Generate and save random key and IV.
        //
        Aes128.GenerateIV();
        Aes128.Key = key;

        Aes128.IV.CopyTo(savedIV, 0);
        using (var encryptor = Aes128.CreateEncryptor())
        using (var msEncrypt = new MemoryStream())
        using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
        using (var bw = new BinaryWriter(csEncrypt, Encoding.UTF8))
        {
           bw.Write(dataToBeEncrypted);
           bw.Close();

           cipherBytes = msEncrypt.ToArray();
        }

Solution

  • The issue was resolved by removing Aes128.Padding = PaddingMode.None; and letting it get padded by PKC7. Also as answered by @Topaco How to turn python AES function into C# code I trimmed the cipher text to plaintext length to remove padding post encryption.

    Updated code :

         using (AesCryptoServiceProvider Aes128 = new AesCryptoServiceProvider())
         {
    
            Aes128.BlockSize = 128;
            Aes128.KeySize = 128;
    
            //
            // Specify CFB8 mode
            //
            Aes128.Mode = CipherMode.CFB;
            Aes128.FeedbackSize = 8;
            //
            // Generate and save random key and IV.
            //
            Aes128.GenerateIV();
            Aes128.Key = key;
    
            Aes128.IV.CopyTo(savedIV, 0);
            using (var encryptor = Aes128.CreateEncryptor())
            using (var msEncrypt = new MemoryStream())
            using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
            using (var bw = new BinaryWriter(csEncrypt, Encoding.UTF8))
            {
               Console.WriteLine("About to binary write.");
               bw.Write(dataToBeEncrypted);
               bw.Close();
               Console.WriteLine("binary write successful.");
    
               cipherBytesWithPadding = msEncrypt.ToArray();
            }
            Buffer.BlockCopy(cipherBytesWithPadding, 0, cipherBytes, 0, dataToBeEncrypted.Length);