ASP.NET WebAPI中AES256解密实现求助
ASP.NET WebAPI 处理AES256加密请求体实现方案
1. 前置确认
先和对接方明确以下AES核心参数,必须完全一致才能解密成功:
- 密钥:确保是256位(32字节),确认是明文还是Base64编码格式
- 加密模式:常见为CBC(需配套IV)或ECB(无需IV)
- 填充模式:通常为PKCS7
- 初始向量(IV):CBC模式下必须提供,长度为16字节
- 加密结果编码:确认是Base64还是UTF8直接转字符串
2. 编写AES解密工具类
封装通用解密逻辑,方便复用:
using System.Security.Cryptography; using System.Text; public static class AesHelper { /// <summary> /// AES256解密 /// </summary> /// <param name="encryptedText">加密后的字符串</param> /// <param name="key">AES密钥(32字节)</param> /// <param name="iv">初始向量(CBC模式必填,16字节)</param> /// <returns>解密后的明文</returns> public static string Decrypt(string encryptedText, string key, string iv = null) { using var aes = Aes.Create(); aes.KeySize = 256; // 若密钥是Base64编码,替换为Convert.FromBase64String(key) aes.Key = Encoding.UTF8.GetBytes(key); aes.Mode = CipherMode.CBC; // 对接方是ECB则改为CipherMode.ECB aes.Padding = PaddingMode.PKCS7; if (!string.IsNullOrEmpty(iv)) { // 若IV是Base64编码,替换为Convert.FromBase64String(iv) aes.IV = Encoding.UTF8.GetBytes(iv); } var decryptor = aes.CreateDecryptor(aes.Key, aes.IV); // 若加密结果是UTF8直接转的字符串,替换为Encoding.UTF8.GetBytes(encryptedText) var encryptedBytes = Convert.FromBase64String(encryptedText); using var ms = new MemoryStream(encryptedBytes); using var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read); using var sr = new StreamReader(cs); return sr.ReadToEnd(); } }
3. 自定义InputFormatter自动解密请求体
让WebAPI自动完成解密+模型绑定,无需控制器手动处理:
using Microsoft.AspNetCore.Mvc.Formatters; using System.Text.Json; public class AesJsonInputFormatter : TextInputFormatter { private readonly string _aesKey; private readonly string _aesIv; public AesJsonInputFormatter(string aesKey, string aesIv) { _aesKey = aesKey; _aesIv = aesIv; // 适配对接方请求的Content-Type,可添加自定义类型如application/aes-json SupportedMediaTypes.Add("application/json"); SupportedEncodings.Add(Encoding.UTF8); } public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding) { var httpContext = context.HttpContext; using var reader = new StreamReader(httpContext.Request.Body, encoding); var encryptedText = await reader.ReadToEndAsync(); try { var decryptedJson = AesHelper.Decrypt(encryptedText, _aesKey, _aesIv); var model = JsonSerializer.Deserialize(decryptedJson, context.ModelType, new JsonSerializerOptions { PropertyNameCaseInsensitive = true // 适配JSON字段与实体属性大小写不一致的情况 }); return await InputFormatterResult.SuccessAsync(model); } catch (Exception ex) { context.ModelState.TryAddModelError(string.Empty, $"解密失败: {ex.Message}"); return await InputFormatterResult.FailureAsync(context.ModelState); } } }
4. 注册自定义格式化器
在Program.cs(.NET 6+)中配置服务,密钥和IV建议从配置文件读取,避免硬编码:
var builder = WebApplication.CreateBuilder(args); // 从appsettings.json读取AES配置 var aesConfig = builder.Configuration.GetSection("AesSettings"); var aesKey = aesConfig["Key"]; var aesIv = aesConfig["IV"]; builder.Services.AddControllers(options => { // 将自定义格式化器放到最前面,优先使用 options.InputFormatters.Insert(0, new AesJsonInputFormatter(aesKey, aesIv)); }); var app = builder.Build(); app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
appsettings.json配置示例:
{ "AesSettings": { "Key": "你的32字节密钥字符串", "IV": "你的16字节IV字符串(CBC模式必填)" } }
5. 控制器接收解密后数据
直接用实体类接收请求,无需手动处理解密:
using Microsoft.AspNetCore.Mvc; [ApiController] [Route("api/external")] public class ExternalController : ControllerBase { [HttpPost("submit")] public IActionResult SubmitData([FromBody] ExternalRequestModel model) { if (!ModelState.IsValid) { return BadRequest(ModelState); } // 直接使用解密后的model进行业务处理 return Ok(new { Status = "Success", ReceivedData = model }); } } // 实体类需与对接方JSON结构一致 public class ExternalRequestModel { public int OrderId { get; set; } public string CustomerName { get; set; } public decimal TotalAmount { get; set; } // 其他字段... }
关键注意事项
- 所有AES参数必须和对接方严格对齐,任何差异都会导致解密失败
- 密钥和IV不要硬编码,可存入配置中心或密钥管理服务(如Azure Key Vault)
- 添加日志记录解密异常,便于排查对接问题
内容的提问来源于stack exchange,提问作者Raj R
相关产品推荐
相关产品推荐

