分享程式代碼相關筆記
目前文章總數:157 篇
最後更新:2024年 12月 07日
1. 控制器 | : | 一個控制器Home,包含上傳圖片(未加密)、上傳圖片(加密) |
2. 檢視頁面 | : | 頁面,包含上傳圖片(未加密)、上傳圖片(加密) |
3. 商務邏輯 | : | 基本驗證、實現上傳檔案到Server、以及加密檔案後再上傳到Server |
4. 加密工具 | : | 實現對稱式加解密AES,目的是上傳時加密圖檔,讀取時解密圖檔 |
5. 測試圖片 | : | 本次的測試圖片,作者自己畫的2張圖,沒有智慧財產權-法律問題 |
選擇上傳圖片明文
頁面,如下圖
選擇一張圖片,可以用範例網站中的TestImage資料夾下的圖片Busy.png做範例
~\\TestImage\\Busy.png
再按下上傳按鈕,上傳檔案
上傳成功後,會立刻刷新頁面看到圖片
我們到Server上看存放的位置,可以發現圖片成功上傳,但是任何人都可以知道圖片內容
假設駭客或內部員工要搞破壞,只要用一個USB就偷光資料了
※圖片上傳後會重新命名為 MyImage.png
~\\WebSiteUplodaImageEncryptExample\\wwwroot\\MyImage\\MyImage.png
選擇上傳圖片加密範例
頁面,如下圖
選擇一張圖片,可以用範例網站中的TestImage資料夾下的圖片BrainStorm.png做範例,並且上傳
~\\TestImage\\BrainStorm.png
上傳成功後,會立刻刷新頁面看到圖片
我們到Server上看存放的位置,可以發現圖片成功上傳,並且已經做過加密
只有透過這個網站用對稱式金鑰解密後才能查看圖片內容
※圖片上傳後會重新命名為 BrainStorm.png
~\\WebSiteUplodaImageEncryptExample\\wwwroot\\MyImage\\BrainStorm.png
HomeController.cs 下我們實現了[HttpPost] Action API
到後端後,呼叫 _upload.UploadImageEncrypt(upload.Image);
/// <summary>
/// 上傳加密圖片
/// </summary>
/// <returns></returns>
[HttpPost]
public IActionResult UpLoadFileEncrypt([FromForm] UploadModel upload)
{
if (ModelState.IsValid)
{
_upload.UploadImageEncrypt(upload.Image);
}
return RedirectToAction("UploadEncryptImageFile", "Home");
}
UploadFileService.cs 實現了加密檔案,並且做上傳的工作
關鍵在呼叫加密工具 var encryptedImageData = CryptoUtil.AesEncrypt(imageData);
下面一行再進行上傳檔案 File.WriteAllBytes(filePath, encryptedImageData);
/// <summary>
/// 上傳圖片-加密
/// </summary>
/// <param name="imageFile"></param>
public void UploadImageEncrypt(IFormFile imageFile)
{
var path = $"{_environment.WebRootPath}\\MyImage";
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
var filePath = Path.Combine(path, "MyEncryptImage.png");
using (MemoryStream ms = new MemoryStream())
{
imageFile.CopyTo(ms);
var imageData = ms.ToArray();
// 將圖片資料進行加密
var encryptedImageData = CryptoUtil.AesEncrypt(imageData);
File.WriteAllBytes(filePath, encryptedImageData);
}
}
加密過程呼叫了 AesEncrypt()
將資料做了AES對稱式加密後輸出byte[]
/// <summary>
/// 1. 自定義固定金鑰
/// </summary>
private const string _AesDefaultKey ="24guDYHrUmj6ll4cIZXmBA8DTY2b8fzN";
/// <summary>
/// 2. AES 加密
/// </summary>
public static byte[] AesEncrypt(byte[] data)
{
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = Encoding.UTF8.GetBytes(_AesDefaultKey);
aesAlg.Mode = CipherMode.ECB;
aesAlg.Padding = PaddingMode.PKCS7;
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
csEncrypt.Write(data, 0, data.Length);
csEncrypt.FlushFinalBlock();
}
return msEncrypt.ToArray();
}
}
}
在圖片檢視時 Views/Home/UploadEncryptImageFile.cshtml 我們進行解密圖片
在Razor的 1.1 與 1.2 部分進行讀圖片,並且做Aes解密,並且轉成base64存在 base64Image變數中
在2. 時,Html的img讀取base64Image變數,使原始圖片可以檢視
<!-- 1-1. 讀取圖檔,並且解密 -->
@inject Microsoft.AspNetCore.Hosting.IWebHostEnvironment WebHostEnvironment
@{
var file = Url.Content("~/MyImage/MyEncryptImage.png");
var appRootPath = WebHostEnvironment.WebRootPath;
var imagePath = System.IO.Path.Combine(appRootPath, "MyImage", "MyEncryptImage.png");
var base64Image = string.Empty;
if(System.IO.File.Exists(imagePath))
{
var imageBytes = System.IO.File.ReadAllBytes(imagePath);
//1-2. AES解密
var originImage = CryptoUtil.AesDecrypt(imageBytes);
base64Image = Convert.ToBase64String(originImage);
}
}
<!-- 2. 圖片讀取內容 -->
<img src="data:image/png;base64,@base64Image" style='max-height:300px; max-width:300px' />