无法解决压缩,加密,解密,解压缩流的实现

时间:2020-07-01 18:00:28

标签: c# stream deflatestream cryptostream

我一直在努力与使用using语句链接,并且无法解决一长串实现问题中的最新问题。我需要压缩,然后加密并将生成的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://docs.microsoft.com/en-us/dotnet/standard/security/walkthrough-creating-a-cryptographic-application https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.rijndaelmanaged?redirectedfrom=MSDN&view=netcore-3.1 Chained GZipStream/DeflateStream and CryptoStream (AES) breaks when reading DeflateStream / GZipStream to CryptoStream and vice versa https://docs.microsoft.com/en-us/dotnet/api/system.io.compression.gzipstream?redirectedfrom=MSDN&view=netcore-3.1#code-snippet-2 How to fix 'Found invalid data while decoding.' Compression/Decompression string with C#

1 个答案:

答案 0 :(得分:0)

经过大约2天的调查,我找到了我的错误。

在解密部分中,我打电话给rjndl.CreateEncryptor而不是rjndl.CreateDecryptor ...(请告诉我,其他人也遇到这种类型的$#!t)

完成测试后,我将更新我的问题代码,以作为将来通过Google在此登陆的任何人的一个很好的例子。