简体   繁体   English

C#使用RijndaelManaged和CryptoStream解密mp3文件

[英]C# Decrypting mp3 file using RijndaelManaged and CryptoStream

I have decrypted and saved an mp3 file into a blob storage. 我已经解密了mp3文件并将其保存到Blob存储中。

However, when I decrypt and download the file I cant play it. 但是,当我解密并下载文件时,无法播放。 I used an Mp3 validation tool which says "unknown file format". 我使用了Mp3验证工具,该工具显示“未知文件格式”。 I believe it is the decryption that does not work since it works to download an unencrypted Mp3 file. 我相信这是解密无效的,因为它可以下载未加密的Mp3文件。 Below I first show the encryption code within its Azure webjob function. 下面我首先显示其Azure webjob函数中的加密代码。 The I show the decryption method and the method using it. 我展示了解密方法和使用它的方法。 I have removed handling of keys and such or clarity. 我已经删除了键的处理,诸如此类。

Encrypt 加密

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 AdminController

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

Recording Service handler 记录服务处理程序

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;
    }

You're trying to write the decrypted data back into the source-stream in your Recording Service handler. 您正在尝试将解密的数据写回到 Recording Service处理程序中的源流中。 This will never work. 这将永远行不通。 I'm amazed this doesn't throw an exception. 我很惊讶这不会引发异常。

You need to set up your input stream, pass it into a decrypting CryptoStream, then write that to another output stream: 您需要设置输入流,将其传递到解密的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();
    }
}

As an aside, the implementation as you've presented it here is full of security issues: 顺便说一句,您在此处介绍的实现充满了安全性问题:

  • Don't use a non-padded cipher. 不要使用非填充密码。 You can leak information this way. 您可以通过这种方式泄漏信息。
  • Don't generate your key from a password. 不要从密码生成密钥。 Use a cryptographically secure RNG to generate your keys. 使用加密安全的RNG生成密钥。
  • If you must use a string as your key's password, use Rfc2898DeriveBytes to generate a cryptographically secure random key from the password. 如果必须使用字符串作为密钥的密码,请使用Rfc2898DeriveBytes从该密码生成加密安全的随机密钥。
  • Absolutely do not use your symmetric key as your IV. 绝对不要将对称密钥用作IV。 This is really, really bad practice. 这确实是非常糟糕的做法。 The IV is used to randomize the cipher's output - it is not a secret in the same way as the key, and should be unique to each 'message' (or file) being encrypted. IV用于随机化密码的输出 -它不是与密钥相同的秘密,并且对于每个要加密的“消息”(或文件)都应该是唯一的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM