我有一个现有的数据格式,其部分内容在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;
答案 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);