C # AES Encryption in CFB where equal text length equals encrypted length

I have an existing data format that has parts of it encrypted in what seems to be AES in CFB mode. The length of the text data and the length of the encrypted data are the same.

In C #, almost every angle I took seems to expect the encrypted length to be a multiple of the block size ... so I get an exception trying to decrypt the data.

When researching solutions, I used Crypto ++ and wrote a quick C ++ application that successfully decrypts the data, so I'm sure I use the correct algorithm, key and IV. This works great, but I would like to keep everything inside C #, if at all possible. Any suggestions?

The working C ++ code is below:

//define key
unsigned char key[16];
//populate key
//...


//define iv
unsigned char iv[16];
//populate iv
//...

std::ifstream inFile;

//open file
inFile.open("file.aes",ios::binary );

//get file size
inFile.seekg(0,ios::end);
int fileSize = (int) inFile.tellg();
inFile.seekg(offset, ios::beg);

//read/close file
char* inBytes = new char[fileSize];
inFile.read(inBytes,fileSize);
inFile.close();

//configure decryption
CFB_Mode<AES>::Decryption cfbDecryption(key, 16, iv);

//populate output bytes
char* outBytes = new char[fileSize];
cfbDecryption.ProcessData((byte*) outBytes,(byte*) inBytes,fileSize);

//open/write/close output file
std::ofstream outFile;
outFile.open("out.dec");
outFile.write(outBytes,fileSize);
outFile.close();

delete[] inBytes;
+1
2

cryptlib, ... :

using cryptlib;

byte[] key = new byte[16] {...key bytes here...};

byte[] iv =  new byte[16] {...iv bytes here...};

byte[] enc;  //ciphertext bytes (i populated them from a filestream)

crypt.Init();
int cryptContext = crypt.CreateContext(crypt.UNUSED, crypt.ALGO_AES);
crypt.SetAttribute(cryptContext, crypt.CTXINFO_MODE, crypt.MODE_CFB);
crypt.SetAttributeString(cryptContext, crypt.CTXINFO_KEY, key, 0, 16);
crypt.SetAttributeString(cryptContext, crypt.CTXINFO_IV, iv, 0, 16);
crypt.Decrypt(cryptContext, enc);   //ciphertext bytes replaced with plaintext bytes
crypt.DestroyContext(cryptContext);
0

, , RijndaelManaged 8- CFB . AesManaged CFB, , , NIST AES . , AES - Rijndael, 128- 128, 192 256- , RijndaelManaged CFB. . # .NET, .

using System;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace AesCFB8Mode
{
    class AESCFB8Example
    {
        static void Example()
        {
            //
            // Encrypt a small sample of data
            //
            String Plain = "The quick brown fox";
            byte[] plainBytes = Encoding.UTF8.GetBytes(Plain);
            Console.WriteLine("plaintext length is " + plainBytes.Length);
            Console.WriteLine("Plaintext is " + BitConverter.ToString(plainBytes));

            byte [] savedKey = new byte[16];
            byte [] savedIV = new byte[16];
            byte[] cipherBytes;
            using (RijndaelManaged Aes128 = new RijndaelManaged())
            {
                //
                // Specify a blocksize of 128, and a key size of 128, which make this
                // instance of RijndaelManaged an instance of AES 128.
                //
                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.GenerateKey();
                Aes128.GenerateIV();

                Aes128.Key.CopyTo(savedKey, 0);
                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(plainBytes);
                    bw.Close();

                    cipherBytes = msEncrypt.ToArray();
                    Console.WriteLine("Cipher length is " + cipherBytes.Length);
                    Console.WriteLine("Cipher text is " + BitConverter.ToString(cipherBytes));
                }
            }

            //
            // Now decrypt the cipher back to plaintext
            //

            using (RijndaelManaged Aes128 = new RijndaelManaged())
            {
                Aes128.BlockSize = 128;
                Aes128.KeySize = 128;
                Aes128.Mode = CipherMode.CFB;
                Aes128.FeedbackSize = 8;
                Aes128.Padding = PaddingMode.None;

                Aes128.Key = savedKey;
                Aes128.IV = savedIV;

                using (var decryptor = Aes128.CreateDecryptor())
                using (var msEncrypt = new MemoryStream(cipherBytes))
                using (var csEncrypt = new CryptoStream(msEncrypt, decryptor, CryptoStreamMode.Read))
                using (var br = new BinaryReader(csEncrypt, Encoding.UTF8))
                {
                    //csEncrypt.FlushFinalBlock();
                    plainBytes = br.ReadBytes(cipherBytes.Length);

                    Console.WriteLine("Decrypted plain length is " + plainBytes.Length);
                    Console.WriteLine("Decrypted plain text is " + BitConverter.ToString(plainBytes));
                }
            }
        }

        static void Main(string[] args)
        {
            Example();
        }
    }
}
+2

Source: https://habr.com/ru/post/1752301/


All Articles