2015-02-24 74 views
0

我解密并将mp3文件保存到blob存储中。C#使用RijndaelManaged和CryptoStream解密mp3文件

但是,当我解密并下载文件时,我无法播放它。我使用了一个说明“未知文件格式”的Mp3验证工具。我相信这是解密不起作用,因为它可以下载未加密的Mp3文件。我首先在Azure webjob函数中显示加密代码。我展示了解密方法和使用它的方法。我已经删除了处理键和这样或清晰。

加密

public static void EncryptBlob(
     [BlobTrigger("callstest/{name}")] 
     [Blob("callstest/{name}", FileAccess.Read)] Stream blobInput, 
     [Blob("encryptedcalls/{name}.vega", FileAccess.Write)] Stream blobOutput) 
    { 
     try 
     { 
      var password = "myKey123"; 
      var ue = new UnicodeEncoding(); 
      var key = ue.GetBytes(password); 
      var rmCrypto = new RijndaelManaged {Padding = PaddingMode.None}; 

      using (var cs = new CryptoStream(blobOutput, 
       rmCrypto.CreateEncryptor(key, key), 
       CryptoStreamMode.Write)) 
      { 
       int data; 
       while ((data = blobInput.ReadByte()) != -1) 
        cs.WriteByte((byte)data); 
      } 

     } 
     catch 
     { 
      Trace.TraceError("an error occured during encryption of the file-get the name?"); 
     } 
    } 

AdminController

public async Task<ActionResult> DownloadMp3FromUrl() 
    { 
     var file = await _recordingService.GetRecordingFromUrl(); 
     var fileName = "filetest.mp3"; 
     return File(file,"audio/mpeg", fileName); 
    } 

录音业务处理

public async Task<byte[]> GetRecordingFromUrl() 
    { 
     var container = _blobClient.GetContainerReference("encryptedcalls"); 

     var blockBlob = container.GetBlockBlobReference("SearchFiles.mp3.vega"); 

     try 
     { 
      var password = "myKey123"; 
      var ue = new UnicodeEncoding(); 
      var key = ue.GetBytes(password); 
      var rmCrypto = new RijndaelManaged { Padding = PaddingMode.None }; 

      using (var stream = new MemoryStream()) 
      { 
       blockBlob.FetchAttributes(); 
       blockBlob.DownloadToStream(stream, null, null); 
       using (var cs = new CryptoStream(stream, rmCrypto.CreateDecryptor(key, key), CryptoStreamMode.Read)) 
       { 
        int data; 
        while ((data = stream.ReadByte()) != -1) 
         cs.WriteByte((byte)data); 

        return stream.ToArray(); 
       } 
      } 
     } 
     catch 
     { 
      Trace.TraceError("an error occured during encryption of the file-get the name?"); 
     } 
     return null; 
    } 

回答

1

你试图解密的数据写回到源流中录制服务处理器。这将无法工作。我很惊讶这不会抛出异常。

你需要设置你的输入流,它传递到解密的CryptoStream,然后写为其他输出流:

using (var inStream = new MemoryStream()) 
using (var outStream = new MemoryStream()) 
{ 
    blockBlob.FetchAttributes(); 
    blockBlob.DownloadToStream(inStream, null, null); 
    using (var cryptoStream = new CryptoStream(
     inStream, rmCrypto.CreateDecryptor(key, key), CryptoStreamMode.Read)) 
    { 
     cryptoStream.CopyTo(outStream); 
     return outStream.ToArray(); 
    } 
} 

顺便说一句,因为你已经在这里介绍它的实现是安全问题全

  • 不要使用非填充密码。你可以通过这种方式泄漏信息。
  • 不要从密码生成密钥。使用cryptographically secure RNG生成您的密钥。
  • 如果您要必须使用字符串作为密钥的密码,请使用Rfc2898DeriveBytes从密码生成密码安全的随机密钥。
  • 绝对不要使用您的对称密钥作为您的IV。这是非常糟糕的做法。 IV用于randomize the cipher's output - 与密钥相同,它不是秘密,并且对每个正在加密的“消息”(或文件)应该是唯一的。