我一直在与链式使用语句作斗争,并且无法解决一长串实现问题中的最新问题。我需要压缩,然后加密生成的 IV 并将其附加到所选文件中。这一切似乎都可以正常工作,但是我无法展开该过程。在查看了几个类似的堆栈帖子和文章后,我仍然无法让它工作,现在需要更直接的帮助。
最新抛出的错误是System.IO.InvalidDataException: 'Found invalid data while decoding.'
解密流似乎没有按预期运行,这让解压缩流变得古怪。
byte[] key;
byte[] salt;
const int keySize = 256;
const int blockSize = keySize;
byte[] iv = new byte[blockSize / 8];//size to bits
RijndaelManaged rjndl;
RNGCryptoServiceProvider cRng;
void InitializeCryptor() {
//Temporarily define the salt & key
salt = Encoding.UTF8.GetBytes("SaltShouldBeAtLeast8Bytes");
key = new Rfc2898DeriveBytes("MyL0ngPa$$phra$e", salt, 4).GetBytes(keySize / 8);
//Initialize the crypto RNG generator
cRng = new RNGCryptoServiceProvider();
// Create instance of Rijndael (AES) for symetric encryption of the data.
rjndl = new RijndaelManaged();
rjndl.KeySize = keySize;
rjndl.BlockSize = blockSize;
rjndl.Mode = CipherMode.CBC;
}
void CompressAndEncryptFile(string relativeFilePath, string fileName) {
//Create a unique IV each time
cRng.GetBytes(iv);
//Create encryptor
rjndl.Key = key;
rjndl.IV = iv;
ICryptoTransform encryptor = rjndl.CreateEncryptor(rjndl.Key, rjndl.IV);
//Create file specific output sub-directory
Directory.CreateDirectory(Path.Combine(outputPath, relativeFilePath));
//Read and compress file into memory stream
using (FileStream readStream = File.OpenRead(Path.Combine(initialpath, relativeFilePath, fileName)))
using (FileStream writeStream = new FileStream(Path.Combine(outputPath, relativeFilePath, fileName + ".dat"), FileMode.Create))
using (CryptoStream encryptStream = new CryptoStream(writeStream, encryptor, CryptoStreamMode.Write))
using (DeflateStream compStream = new DeflateStream(encryptStream, CompressionLevel.Optimal)) {
//Write the following to the FileStream for the encrypted file:
// - length of the IV
// - the IV
byte[] ivSize = BitConverter.GetBytes(rjndl.IV.Length);
writeStream.Write(ivSize, 0, 4);
writeStream.Write(rjndl.IV, 0, rjndl.BlockSize / 8);
readStream.CopyTo(compStream);
}
}
void DecryptAndDecompressFile(string relativeFilePath) {
string outputPath = Path.Combine(initialpath, "Unpack");
Directory.CreateDirectory(outputPath);
using (FileStream readStream = new FileStream(Path.Combine(initialpath, manifestData.version, relativeFilePath + ".dat"), FileMode.Open)) {
byte[] tmpLength = new byte[4];
//Read length of IV
readStream.Seek(0, SeekOrigin.Begin);
readStream.Read(tmpLength, 0, 3);
int ivLength = BitConverter.ToInt32(tmpLength, 0);
byte[] readIv = new byte[ivLength];
//Read IV
readStream.Seek(4, SeekOrigin.Begin);
readStream.Read(readIv, 0, ivLength);
rjndl.IV = readIv;
//Start at beginning of encrypted data
readStream.Seek(4 + ivLength, SeekOrigin.Begin);
//Create decryptor
ICryptoTransform decryptor = rjndl.CreateEncryptor(key, readIv);
using (CryptoStream decryptStream = new CryptoStream(readStream, decryptor, CryptoStreamMode.Read))
using (DeflateStream decompStream = new DeflateStream(decryptStream, CompressionMode.Decompress))
using (FileStream writeStream = new FileStream(Path.Combine(outputPath, relativeFilePath), FileMode.Create)) {
decompStream.CopyTo(writeStream);
}
}
}
对于那些喜欢指出其他类似的堆栈问题并在不提供支持的情况下投票关闭/复制的人,以下是我首先完成的线程和帖子,每个都没有成功。 https://learn.microsoft.com/en-us/dotnet/standard/security/walkthrough-creating-a-cryptographic-application https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.rijndaelmanaged?redirectedfrom=MSDN&view=netcore-3.1 链式GZipStream/DeflateStream和CryptoStream(AES(在读取时中断 DeflateStream/GZipStream to CryptoStream,反之亦然 https://learn.microsoft.com/en-us/dotnet/api/system.io.compression.gzipstream?redirectedfrom=MSDN&view=netcore-3.1#code-snippet-2 如何修复"解码时发现无效数据"。 使用 C# 压缩/解压缩字符串
经过~2天的调查,我找到了我的错误。
我在解密部分打电话给rjndl.CreateEncryptor
而不是rjndl.CreateDecryptor
......(请告诉我这种类型的$#!t也发生在其他人身上(
完成测试后,我将更新我的问题代码,为将来通过谷歌登陆这里的任何人提供一个很好的例子。