AES填充并将密文写入磁盘文件

我有一个字符串,我用C ++使用Crypto ++加密以下mehtod:

std::ifstream t(filename); //File to be encrypt std::stringstream buffer; buffer << t.rdbuf(); ofstream combined_file2(filename2); //Encrypted file combined_file2 << encrypt(buffer.str()); string encrypt(string data) { // Key and IV setup std::string key = "0123456789abcdef"; std::string iv = "aaaaaaaaaaaaaaaa"; //Alternative //byte key[CryptoPP::AES::DEFAULT_KEYLENGTH], iv[CryptoPP::AES::BLOCKSIZE]; //memset(key, 0x00, CryptoPP::AES::DEFAULT_KEYLENGTH); //memset(iv, 0x00, CryptoPP::AES::BLOCKSIZE); std::string plaintext = data; std::string ciphertext; // Create Cipher Text CryptoPP::AES::Encryption aesEncryption((byte *)key.c_str(), CryptoPP::AES::DEFAULT_KEYLENGTH); CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption(aesEncryption, (byte *)iv.c_str()); //Alternative //CryptoPP::AES::Encryption aesEncryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH); //CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption(aesEncryption, iv); CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::StringSink(ciphertext)); stfEncryptor.Put(reinterpret_cast(plaintext.c_str()), plaintext.length() + 1); stfEncryptor.MessageEnd(); return ciphertext; } 

当我尝试在我的C#应用​​程序中解密文件时,我收到消息,数据的长度无效。 我认为字节数组的长度不是16的倍数,所以我得到了错误。 我尝试使用填充,但它无法正常工作。

这是我解密文件的方式:

 string plaintext = Decrypt(File.ReadAllBytes(path)); private static string Decrypt(byte[] cipherText) { if (cipherText == null || cipherText.Length <= 0) throw new ArgumentNullException("cipherText"); byte[] Key = GetBytes(ConfigurationManager.AppSettings["aes_key"]); byte[] IV = GetBytes(ConfigurationManager.AppSettings["aes_iv"]); // Declare the string used to hold the decrypted text. string plaintext = null; // Create an RijndaelManaged object with the specified key and IV. using (RijndaelManaged rijAlg = new RijndaelManaged()) { rijAlg.Key = Key; //rijAlg.IV = IV; //for testing rijAlg.IV = new byte[] { 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97 }; // Create a decrytor to perform the stream transform. ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV); // Create the streams used for decryption. using (MemoryStream msDecrypt = new MemoryStream(cipherText)) { using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) { using (StreamReader srDecrypt = new StreamReader(csDecrypt)) { // Read the decrypted bytes from the decrypting stream // and place them in a string. plaintext = srDecrypt.ReadToEnd(); } } } } return plaintext; } 

我该如何解决这个问题? 是否有任何function来填充,或者填充是错误的方法?

根据评论:

在C ++中我保存了一个文件combined_file2 << encrypt(buffer.str()); 我在C#程序中读到的字符串明文= Decrypt(File.ReadAllBytes(path));

我不认为嵌入式NULL会导致encrypt函数出现问题,因为它返回一个string ,并且包含一个显式长度。

但是,嵌入的NULL以及文件在C ++中写入磁盘的方式(或从C#中的磁盘读取)将是一个问题,因为这将在第一个嵌入的NULL停止: combined_file2 << encrypt(buffer.str())

也许以下内容会有所帮助:

 StringSource ss(ciphertext, true /*pumpAll*/); FileSink fs("my-encrypted-file.bin", true /*binary*/); ss.TransferTo(fs); 

如果您使用的是C ++流,则在流对象上使用write方法:

 ofstream combined_file2; ... combined_file2.write(ciphertext.data(), ciphertext.size());