C#解密使用RijndaelManaged的和CryptoStream的MP3文件 [英] C# Decrypting mp3 file using RijndaelManaged and CryptoStream

查看:224
本文介绍了C#解密使用RijndaelManaged的和CryptoStream的MP3文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经解密并保存MP3文件到Blob存储。

然而,当我解密和下载的文件我不能播放。我用一个MP3的验证工具,它说:未知文件格式。我认为这是不工作,因为它的工作原理,下载未加密的MP3文件解密。下面我第一次展现其Azure的webjob函数内部加密code。在我展示解密方法和使用它的方法。我已删除键和这样或清晰的处理。

加密

 公共静态无效EncryptBlob(
      [BlobTrigger(callstest / {名})]
      [斑点(callstest /(名称),FileAccess.Read)流blobInput,
      [斑点(encryptedcalls / {name}的.vega,FileAccess.Write)流blobOutput)
    {
        尝试
        {
            VAR密码=myKey123;
            VAR UE =新的Uni codeEncoding();
            VAR键= ue.GetBytes(密码);
            VAR rmCrypto =新RijndaelManaged的{填充= PaddingMode.None};            使用(VAR CS =新的CryptoStream(blobOutput,
                rmCrypto.CreateEncryptor(键,键),
                CryptoStreamMode.Write))
            {
                int数据;
                而((数据= blobInput.ReadByte())!= -1)
                    cs.WriteByte((字节)的数据);
            }        }
        抓住
        {
            Trace.TraceError(加密过程中发生了错误的文件,得到的名字吗?);
        }
    }

AdminController

 公共异步任务<&的ActionResult GT; DownloadMp3FromUrl()
    {
        var文件=等待_recordingService.GetRecordingFromUrl();
        变种文件名=filetest.mp3;
        返回File(文件,音频/ MPEG,文件名);
    }

录音服务处理器

 公共异步任务<字节[]> GetRecordingFromUrl()
    {
        变种容器= _blobClient.GetContainerReference(encryptedcalls);        变种blockBlob = container.GetBlockBlobReference(SearchFiles.mp3.vega);        尝试
        {
            VAR密码=myKey123;
            VAR UE =新的Uni codeEncoding();
            VAR键= ue.GetBytes(密码);
            VAR rmCrypto =新RijndaelManaged的{填充= PaddingMode.None};            使用(VAR流=新的MemoryStream())
            {
                blockBlob.FetchAttributes();
                blockBlob.DownloadToStream(流,NULL,NULL);
                使用(VAR CS =新的CryptoStream(流rmCrypto.CreateDecryptor(键,键),CryptoStreamMode.Read))
                {
                    int数据;
                    而((数据= stream.ReadByte())!= -1)
                        cs.WriteByte((字节)的数据);                    返回stream.ToArray();
                }
            }
        }
        抓住
        {
            Trace.TraceError(加密过程中发生了错误的文件,得到的名字吗?);
        }
        返回null;
    }


解决方案

您正试图解密后的数据写的的放入您的录音服务处理程序源流。这不会工作。我很惊讶,这并不抛出异常。

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

 使用(VAR inStream中=新的MemoryStream())
使用(VAR outStream =新的MemoryStream())
{
    blockBlob.FetchAttributes();
    blockBlob.DownloadToStream(插播广告,NULL,NULL);
    使用(VAR的CryptoStream =新的CryptoStream(
        视频插播rmCrypto.CreateDecryptor(键,键),CryptoStreamMode.Read))
    {
        cryptoStream.CopyTo(outStream);
        返回outStream.ToArray();
    }
}

顺便说一句,执行如你$ P $这里psented它的完全的安全问题:


  • 请不要使用非填充密码。您可以泄露信息的这种方式。

  • 请不要生成一个密码密钥。使用<一个href=\"https://msdn.microsoft.com/en-us/library/system.security.cryptography.rngcryptoserviceprovider%28v=vs.110%29.aspx\"相对=nofollow>密码安全RNG 来生成你的钥匙。

  • 如果您的必须的使用字符串作为你的密钥的密码,使用Rfc2898DeriveBytes来生成密码的加密安全随机密钥。

  • 绝对的的使用对称密钥作为IV。这是真的,真的不好的做法。该四用于随机密码的输出 - 这是不以同样的方式作为一个秘密键,并应是唯一的被加密的每个信息(或文件)。

I have decrypted and saved an mp3 file into a blob storage.

However, when I decrypt and download the file I cant play it. I used an Mp3 validation tool which says "unknown file format". I believe it is the decryption that does not work since it works to download an unencrypted Mp3 file. Below I first show the encryption code within its Azure webjob function. 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

 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. 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:

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.
  • If you must use a string as your key's password, use Rfc2898DeriveBytes to generate a cryptographically secure random key from the password.
  • Absolutely do not use your symmetric key as your 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.

这篇关于C#解密使用RijndaelManaged的和CryptoStream的MP3文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆