C# 使用 RijndaelManaged 和 CryptoStream 解密 mp3 文件
C# Decrypting mp3 file using RijndaelManaged and CryptoStream
我已经解密了一个 mp3 文件并将其保存到 blob 存储中。
但是,当我解密并下载文件时,我无法播放。我使用了一个 Mp3 验证工具,上面写着 "unknown file format"。我相信是解密不起作用,因为它可以下载未加密的 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?");
}
}
管理员控制器
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;
}
您正在尝试将解密的数据写回到您的录制服务处理程序中的源流中。这永远行不通。我很惊讶这不会引发异常。
您需要设置输入流,将其传递到解密 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 - 它不是与密钥相同的秘密,并且对于每个被加密的 'message'(或文件)应该是唯一的。
我已经解密了一个 mp3 文件并将其保存到 blob 存储中。
但是,当我解密并下载文件时,我无法播放。我使用了一个 Mp3 验证工具,上面写着 "unknown file format"。我相信是解密不起作用,因为它可以下载未加密的 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?");
}
}
管理员控制器
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;
}
您正在尝试将解密的数据写回到您的录制服务处理程序中的源流中。这永远行不通。我很惊讶这不会引发异常。
您需要设置输入流,将其传递到解密 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 - 它不是与密钥相同的秘密,并且对于每个被加密的 'message'(或文件)应该是唯一的。