Asp.net mvc 3 从Windows Azure存储下载加密文件
我已经创建了一个MVC WebRole Window Azure应用程序,在该应用程序中,我使用对称算法(Rijndael)将加密文件上载到Azure blob存储,如下所示 控制器>动作是Asp.net mvc 3 从Windows Azure存储下载加密文件,asp.net-mvc-3,azure-storage,azure-web-roles,encryption-symmetric,Asp.net Mvc 3,Azure Storage,Azure Web Roles,Encryption Symmetric,我已经创建了一个MVC WebRole Window Azure应用程序,在该应用程序中,我使用对称算法(Rijndael)将加密文件上载到Azure blob存储,如下所示 控制器>动作是 [HttpPost] public ActionResult UploadImage_post(HttpPostedFileBase fileBase) { if (fileBase.ContentLength > 0) { // Retrieve a reference
[HttpPost]
public ActionResult UploadImage_post(HttpPostedFileBase fileBase)
{
if (fileBase.ContentLength > 0)
{
// Retrieve a reference to a container
Microsoft.WindowsAzure.StorageClient.CloudBlobContainer blobContainer =
_myBlobStorageService.GetCloudBlobContainer();
Microsoft.WindowsAzure.StorageClient.CloudBlob blob =
blobContainer.GetBlobReference(fileBase.FileName);
using (BlobStream blobStream = blob.OpenWrite())
{
string encryptionKey = //somekey;
byte[] file = new byte[fileBase.ContentLength];
EncDecAlgo.EncryptBlobFile(file, blobStream, encryptionKey);
}
}
}
public void EncryptBlobFile(byte[] file, BlobStream bs, string key)
{
PasswordDeriveBytes pdb = new PasswordDeriveBytes(key,
new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d,
0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76});
Rijndael alg = Rijndael.Create();
alg.Key = pdb.GetBytes(32);
alg.IV = pdb.GetBytes(16);
CryptoStream cs = new CryptoStream(bs,
alg.CreateEncryptor(), CryptoStreamMode.Write);
foreach (var data in file)
{
cs.WriteByte((byte)data);
}
cs.Close();
bs.Close();
}
上面的文件加密工作正常
下载的代码是
public ActionResult DownloadFile(string filename)
{
// Retrieve reference to a previously created container.
Microsoft.WindowsAzure.StorageClient.CloudBlobContainer blobContainer =
_myBlobStorageService.GetCloudBlobContainer();
Microsoft.WindowsAzure.StorageClient.CloudBlob blob =
blobContainer.GetBlobReference(filename);
blob.FetchAttributes();
string encryptionKey = //same key used in encryption;
using (BlobStream blobStream = blob.OpenRead())
{
EncDecAlgo.DecryptBlobFile(blobStream, encryptionKey, filename);
}
}
public static void DecryptBlobFile(BlobStream bs, string key, string filePath)
{
try
{
PasswordDeriveBytes pdb = new PasswordDeriveBytes(key,
new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65,
0x64, 0x76, 0x65, 0x64, 0x65, 0x76});
Rijndael alg = Rijndael.Create();
alg.Key = pdb.GetBytes(32);
alg.IV = pdb.GetBytes(16);
CryptoStream cs = new CryptoStream(bs,
alg.CreateDecryptor(), CryptoStreamMode.Read);
// Decrypt & Download Here
System.Web.HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + Path.GetFileName(filePath));
System.Web.HttpContext.Current.Response.ContentType = "application/" + Path.GetExtension(filePath).Replace(".", "");
int data;
while ((data = cs.ReadByte()) != -1)
{
if (data != 0)
{
}
System.Web.HttpContext.Current.Response.OutputStream.WriteByte((byte)data);
System.Web.HttpContext.Current.Response.Flush();
}
cs.Close();
bs.Close();
}
catch
{
}
}
下载时获取以下错误
Server cannot set content type after HTTP headers have been sent.
请提出一些解决方案。这应该相当简单,希望这足以让您开始:
public class CloudFileResult : ActionResult
{
private string m_FileName;
private CloudBlobContainer m_Container;
public CloudFileResult(string imageName, CloudBlobContainer container)
{
if (string.IsNullOrEmpty(imageName))
{
throw new ArgumentNullException("imageName");
}
if (container == null)
{
throw new ArgumentNullException("container");
}
m_FileName = imageName;
m_Container = container;
}
public override void ExecuteResult(ControllerContext context)
{
context.HttpContext.Response.Clear();
var blockBlob = m_Container.GetBlockBlobReference(m_FileName);
blockBlob.FetchAttributes();
context.HttpContext.Response.ContentType = blockBlob.Metadata["ContentType"];
const string key = "my secret";
using (var pdb = new Rfc2898DeriveBytes(key, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 }))
{
using (var alg = RijndaelManaged.Create())
{
alg.Key = pdb.GetBytes(32);
alg.IV = pdb.GetBytes(16);
using (var stream = new CryptoStream(context.HttpContext.Response.OutputStream, alg.CreateDecryptor(), CryptoStreamMode.Write))
{
blockBlob.DownloadToStream(stream);
}
}
}
}
}
static void UploadFileToCloud(CloudBlobContainer container, HttpPostedFileBase file)
{
const string key = "my secret";
using (var pdb = new Rfc2898DeriveBytes(key, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 }))
{
using (var alg = RijndaelManaged.Create())
{
alg.Key = pdb.GetBytes(32);
alg.IV = pdb.GetBytes(16);
var blockBlob = container.GetBlockBlobReference(file.FileName);
using (var stream = new CryptoStream(file.InputStream, alg.CreateEncryptor(), CryptoStreamMode.Read))
{
blockBlob.UploadFromStream(stream);
}
blockBlob.Metadata.Add("ContentType", file.ContentType);
blockBlob.SetMetadata();
}
}
}
static CloudBlobContainer GetContainer()
{
string connection = "DefaultEndpointsProtocol=http;AccountName=AzureAccount;AccountKey=AzureAccountKey;";
var account = CloudStorageAccount.Parse(connection);
var client = account.CreateCloudBlobClient();
var container = client.GetContainerReference("container");
return container;
}
至于下载,您可以简单使用:
[HttpGet]
public ActionResult Index(string fileName)
{
if (!string.IsNullOrEmpty(fileName))
{
return new CloudFileResult(fileName, GetContainer());
}
return View();
}
指针:
- 我更喜欢使用托管加密算法
- 我将原始文件的contenttype存储在blob元数据中(这样您就知道如何为其提供服务)
- catch{}让我毛骨悚然,至少在某个地方记录了异常
- 与其使用HttpContext.Response,不如创建自定义ActionResult
- 总是处理可识别的东西