C#如何结合AES加密实现.NET Core大附件上传的加密存储?
·
大文件传输系统建设方案(.NET技术栈版)
一、核心需求分析与技术选型
作为项目负责人,针对当前大文件传输需求面临的开源组件不可靠、跨平台兼容性差、授权成本控制三大挑战,提出以下技术方案:
-
技术栈匹配策略
- 后端:ASP.NET WebForm(兼容旧系统)+ .NET Core(新项目)双引擎
- 前端:统一封装Vue2/Vue3/React上传组件,通过适配器模式实现接口统一
- 加密层:集成.NET Security库实现SM4(通过BouncyCastle移植)
- 分片传输:基于HTTP Range协议自研分片引擎(兼容IE8)
-
关键问题解决方案
二、核心功能实现代码
1. 后端ASP.NET WebForm分片接收接口(兼容.NET Core)
// FileTransferHandler.ashx (WebForm)
public class FileTransferHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
try
{
var action = context.Request["action"];
var chunkNumber = int.Parse(context.Request["chunkNumber"]);
var totalChunks = int.Parse(context.Request["totalChunks"]);
var fileId = context.Request["fileId"];
var algorithm = context.Request["algorithm"] ?? "SM4"; // 默认国密
if (action == "upload")
{
// 接收分片
var chunkPath = Path.Combine(
context.Server.MapPath("~/App_Data/UploadTemp"),
fileId,
$"chunk_{chunkNumber}");
Directory.CreateDirectory(Path.GetDirectoryName(chunkPath));
context.Request.Files[0].SaveAs(chunkPath);
// 更新数据库记录
UpdateChunkStatus(fileId, chunkNumber, totalChunks);
context.Response.Write("{\"status\":\"success\"}");
}
else if (action == "merge")
{
// 合并分片(流式处理避免内存爆炸)
var outputPath = Path.Combine(
context.Server.MapPath("~/App_Data/UploadComplete"),
$"{fileId}.dat");
using (var fs = new FileStream(outputPath, FileMode.Create))
{
for (int i = 0; i < totalChunks; i++)
{
var chunkPath = Path.Combine(
context.Server.MapPath("~/App_Data/UploadTemp"),
fileId,
$"chunk_{i}");
if (File.Exists(chunkPath))
{
var chunkData = File.ReadAllBytes(chunkPath);
// 加密存储(示例为SM4伪代码)
if (algorithm == "SM4")
{
chunkData = SM4Encrypt(chunkData, GetEncryptionKey());
}
fs.Write(chunkData, 0, chunkData.Length);
File.Delete(chunkPath);
}
}
}
// 清理临时目录
Directory.Delete(
Path.Combine(context.Server.MapPath("~/App_Data/UploadTemp"), fileId),
true);
context.Response.Write("{\"status\":\"merged\"}");
}
}
catch (Exception ex)
{
context.Response.StatusCode = 500;
context.Response.Write($"{{\"error\":\"{ex.Message}\"}}");
}
}
private void UpdateChunkStatus(string fileId, int chunkNumber, int totalChunks)
{
// 使用Dapper操作SQL Server/MySQL/Oracle(通过配置切换)
using (var conn = DatabaseFactory.GetConnection())
{
conn.Execute(@"
UPDATE FileChunks
SET UploadedChunks = @UploadedChunks
WHERE FileId = @FileId",
new { FileId = fileId, UploadedChunks = chunkNumber + 1 });
}
}
}
2. 前端Vue2上传组件(IE8兼容版)
// FileUploader.vue
export default {
data() {
return {
chunkSize: 10 * 1024 * 1024, // 10MB分片
fileId: '',
totalChunks: 0,
currentChunk: 0,
algorithm: 'SM4' // 默认国密
}
},
methods: {
// 初始化上传(兼容IE8的File API检测)
initUpload(file) {
if (!window.FileReader && !window.File) {
alert('您的浏览器不支持大文件上传,请使用Chrome/Firefox');
return;
}
this.fileId = this.generateFileId(file);
this.totalChunks = Math.ceil(file.size / this.chunkSize);
// 初始化数据库记录(通过隐藏iframe调用ASP.NET接口)
this.initDatabaseRecord(file);
// 开始上传第一个分片
this.uploadChunk(file, 0);
},
// 上传分片(IE8兼容的XMLHttpRequest)
uploadChunk(file, chunkIndex) {
if (chunkIndex >= this.totalChunks) {
this.$emit('complete');
return;
}
const start = chunkIndex * this.chunkSize;
const end = Math.min(file.size, start + this.chunkSize);
const chunk = file.slice(start, end);
const formData = new FormData();
formData.append('file', chunk);
formData.append('chunkNumber', chunkIndex);
formData.append('totalChunks', this.totalChunks);
formData.append('fileId', this.fileId);
formData.append('algorithm', this.algorithm);
// 创建兼容IE8的AJAX请求
const xhr = this.createXHR();
xhr.open('POST', '/FileTransferHandler.ashx?action=upload', true);
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
this.currentChunk = chunkIndex + 1;
// 使用localStorage持久化进度(IE8+支持)
localStorage.setItem(`upload_${this.fileId}`, JSON.stringify({
current: this.currentChunk,
total: this.totalChunks
}));
this.uploadChunk(file, this.currentChunk);
} else {
this.$emit('error', '上传失败');
}
}
};
xhr.send(formData);
},
// 创建兼容IE8的XHR对象
createXHR() {
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
} else if (window.ActiveXObject) {
return new ActiveXObject("Microsoft.XMLHTTP");
}
}
},
mounted() {
// 页面刷新时恢复上传进度
const savedProgress = localStorage.getItem(`upload_${this.fileId}`);
if (savedProgress) {
const progress = JSON.parse(savedProgress);
this.currentChunk = progress.current;
}
}
}
3. 数据库设计(SQL Server示例)
CREATE TABLE FileTransferTasks (
Id UNIQUEIDENTIFIER PRIMARY KEY DEFAULT NEWID(),
FileId VARCHAR(64) NOT NULL UNIQUE,
FileName NVARCHAR(255) NOT NULL,
TotalSize BIGINT NOT NULL,
TotalChunks INT NOT NULL,
UploadedChunks INT DEFAULT 0,
EncryptionAlgorithm VARCHAR(16) DEFAULT 'SM4',
Status TINYINT DEFAULT 0, -- 0:上传中 1:已完成 2:失败
CreateTime DATETIME DEFAULT GETDATE(),
UpdateTime DATETIME DEFAULT GETDATE()
);
CREATE TABLE FileChunks (
Id INT IDENTITY(1,1) PRIMARY KEY,
FileId VARCHAR(64) NOT NULL,
ChunkIndex INT NOT NULL,
UploadedTime DATETIME DEFAULT GETDATE(),
FOREIGN KEY (FileId) REFERENCES FileTransferTasks(FileId)
);
三、商业解决方案选型建议
基于公司20万年度预算和央企合作资质要求,推荐以下方案:
-
推荐产品:XX企业文件传输系统(年度授权版)
- 授权模式:年度订阅(不限项目数)
- 核心优势:
- 完全兼容ASP.NET WebForm/.NET Core
- 提供SM4算法的.NET实现库
- 内置WebDAV文件夹解析引擎
- 通过阿里云OSS官方认证
-
资质验证文件清单:
- 合同原件:国家电网2023年采购合同(金额198万)
- 信创认证:通过金融行业信创适配验证
- 典型案例:中国石油、中国联通等6家央企实施案例
- 银行转账凭证:可提供加盖公章的复印件
-
成本对比:
方案 单项目授权 20项目总成本 年度订阅成本 竞品A ¥18,000 ¥360,000 - 推荐方案 - - ¥198,000 谈判后价格 - - ¥185,000
四、实施路线图
-
第一阶段(3周):
- 完成WebForm与.NET Core双模式适配
- 开发IE8兼容层
- 搭建SQL Server测试环境
-
第二阶段(2周):
- 性能优化(10万文件并发下载测试)
- 阿里云OSS集成
- SM4加密传输链路加固
-
第三阶段(1周):
- 全量回归测试(含信创环境)
- 编写开发文档
- 培训技术支持团队
五、风险控制措施
-
兼容性保障:
- 建立IE8专用测试用例库
- 使用BrowserStack进行跨浏览器验证
-
性能保障:
- 实现动态分片大小调整(根据网络状况自动优化)
- 采用阿里云OSS分片上传API减轻服务器压力
-
数据安全:
- 实现传输层SSL加密+存储层SM4加密双保险
- 通过等保2.0三级认证
该方案已通过技术可行性验证,可满足公司高稳定性、低成本、全兼容的核心需求,建议尽快启动商务谈判流程,争取在预算内获得最优授权条件。
设置框架
安装.NET Framework 4.7.2
https://dotnet.microsoft.com/en-us/download/dotnet-framework/net472
框架选择4.7.2
添加3rd引用

编译项目

NOSQL
NOSQL无需任何配置可直接访问页面进行测试
SQL
使用IIS
大文件上传测试推荐使用IIS以获取更高性能。
使用IIS Express
小文件上传测试可以使用IIS Express
创建数据库

配置数据库连接信息

检查数据库配置

访问页面进行测试

相关参考:
文件保存位置,
效果预览
文件上传

文件刷新续传
支持离线保存文件进度,在关闭浏览器,刷新浏览器后进行不丢失,仍然能够继续上传
文件夹上传
支持上传文件夹并保留层级结构,同样支持进度信息离线保存,刷新页面,关闭页面,重启系统不丢失上传进度。
批量下载
支持文件批量下载
下载续传
文件下载支持离线保存进度信息,刷新页面,关闭页面,重启系统均不会丢失进度信息。
文件夹下载
支持下载文件夹,并保留层级结构,不打包,不占用服务器资源。
下载完整示例
更多推荐


所有评论(0)