ITHit Webdav下载和解密office文档

时间:2016-02-18 10:56:32

标签: c# io webdav ithit-webdav-server

我需要在webdav服务器中下载解密的文件office文档,因为文件系统中的文档是加密的。 我正在使用ITHit来实现webdav服务器..并稍微修改代码以便能够解密文件。但是这段代码不起作用。该文件将无法打开并显示“文件xxx无法打开”。它仅适用于未加密的文件。任何人都可以帮助我为什么这段代码不起作用?

private async Task readInternalAsync(Stream output, long startIndex, long count)
{
  var buffer = new byte[bufSize];
  var document = this.documentManagement.GetDocumentById("1");

  using (var fileStream = fileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.Read))
  {
       try
       {
           if (document.EncryptionInfo.IsEncrypted)
           {
                // byte array after the file has been decrypted 
                byte[] data = this.encryptionManagement.DecryptFile(fileStream, document.EncryptionInfo.Password, document.EncryptionInfo.AlgorithmName);
                await output.WriteAsync(data, 0, data.Length);
           }
           else
           {
                fileStream.Seek(startIndex, SeekOrigin.Begin);
                int bytesRead;
                var toRead = (int)Math.Min(count, bufSize);

                while (toRead > 0 && (bytesRead = await fileStream.ReadAsync(buffer, 0, toRead)) > 0)
                {
                     await output.WriteAsync(buffer, 0, bytesRead);
                     count -= bytesRead;
                }
            }
            catch (HttpException ex)
            {
                var msg = ex.Message;
                // The remote host closed the connection (for example Cancel or Pause pressed).
            }
       }
  }
}

如果有人需要,这是解密文件的逻辑。

 public byte[] DecryptFile(Stream inputStream, string passPhrase, string algorithmName)
    {
        using (var outputStream = new MemoryStream())
        {
            this.decryptInputStreamToOutputStream(inputStream, outputStream, passPhrase, algorithmName);
            var bytes = outputStream.ToArray();
            return bytes;
        }
    }

private void decryptInputStreamToOutputStream(Stream inputStream, Stream outputStream, string passPhrase, string algorithmName)
    {
        inputStream.Position = 0;

        algorithmName = this.getAlgorithmName(algorithmName);
        using (var algo = SymmetricAlgorithm.Create(algorithmName))
        {
            // Get the saltbytes by extracting the first 32 bytes from the supplied cipherText bytes.
            var saltBytesCount = algo.BlockSize / 8;
            var saltBytes = new byte[saltBytesCount];
            inputStream.Read(saltBytes, 0, saltBytesCount);

            // Get the IV bytes by extracting the next 32 bytes from the supplied cipherText bytes.
            var ivBytesCount = algo.BlockSize / 8;
            var ivBytes = new byte[ivBytesCount];
            inputStream.Read(ivBytes, 0, ivBytesCount);

            using (var password = new Rfc2898DeriveBytes(passPhrase, saltBytes))
            {
                var keyBytes = password.GetBytes(algo.KeySize / 8);

                using (var decryptor = algo.CreateDecryptor(keyBytes, ivBytes))
                {
                    using (var cryptoStream = new CryptoStream(outputStream, decryptor, CryptoStreamMode.Write))
                    {
                        int count = 0;
                        byte[] data = new byte[this.chryptoChunkBlockSizeBytes];
                        do
                        {
                            count = inputStream.Read(data, 0, this.chryptoChunkBlockSizeBytes);
                            cryptoStream.Write(data, 0, count);
                        }
                        while (count > 0);

                        cryptoStream.FlushFinalBlock();
                    }
                }
            }
        }
    }

非常感谢

此致

1 个答案:

答案 0 :(得分:1)

您的问题可能是文件的长度。正如另一个问题所述,必须正确提供文件的长度。在解密期间,大小可能与原始文件不同。所以一定要将解密后的文件大小称为ContentLength

public long ContentLength
{
   //Supply Decrypted file length here....
   get { return fileInfo.Length; }
}

您也可以尝试在Output.WriteAsync之前设置内容长度......如下所示:

context.Response.ContentLength = data.LongLength();