2016-02-18 4 views
0

Мне нужно загрузить файл расшифрованного файлового офиса на сервере webdav, потому что документ в файловой системе зашифрован. Я использую ITHit для реализации webdav-сервера .. и немного модифицирую код, чтобы иметь возможность расшифровать файл. Однако этот код не работает. Файл не открывается и говорит: «Файл xxx не может быть открыт». Это работает только для незашифрованного файла. Может ли кто-нибудь помочь мне, почему этот код не работает?ITHit Webdav Загрузите и расшифруйте офисный документ

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

Ваша проблема может быть длина файла. Как задано в другом вопросе, длина файла должна быть правильно поставлена. Во время дешифрования размер может отличаться от исходного файла. Поэтому убедитесь, что снабжение расшифрованного размера файла, как ContentLength

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

Вы также можете попытаться установить Content lengt перед тем Output.WriteAsync ... как это:

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