CFB中的C#AES加密,其中明文长度等于加密长度

时间:2012-03-02 22:45:52

标签: c# c++ encryption aes

我有一个现有的数据格式,其部分内容在CFB模式下似乎是AES加密。明文数据长度和加密数据长度相同。

在C#中,几乎我所采取的每个角度似乎都希望加密长度是块大小的倍数...所以我试图解密数据时遇到异常。

在研究解决方案时,我使用了Crypto ++并编写了一个成功解密数据的快速C ++应用程序,所以我很确定我使用的是正确的算法,密钥和IV。这很好用,但我想尽可能保留C#中的所有内容。有什么建议吗?

下面的C ++代码:

//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;

2 个答案:

答案 0 :(得分:3)

这是一个示例,说明如何使用RijndaelManaged类实现8位反馈CFB加密。 AesManaged不支持CFB,因为我认为官方的NIST AES不支持CFB。通过注意AES 只是Rijndael仅限于128位块大小以及128,192和256位密钥大小,您可以使用RijndaelManaged类来获取CFB功能。注意:我不是C#或.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();
        }
    }
}

答案 1 :(得分:0)

我重新尝试使用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);