2016-02-18 80 views
0

我需要在webdav服務器上下載解密的文檔office文檔,因爲文件系統中的文檔是加密的。 我使用ITHit來實現webdav服務器..並稍微修改代碼以便能夠解密文件。但是,此代碼不起作用。該文件不會打開並且顯示「文件xxx無法打開」。它只適用於未加密的文件。任何人都可以幫助我爲什麼這段代碼不會工作?ITHit Webdav下載並解密office文檔

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

你的問題可能是該文件的長度。正如另一個問題所問,文件的長度必須正確提供。在解密期間,大小可能與原始文件不同。所以一定要suply解密文件大小的ContentLength

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

你也可以嘗試Output.WriteAsync之前設置內容lengt ......這樣的:

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