如何在两个ASP.NET MVC站点间传输并读取加密JSON数据
实现ASP.NET MVC站点间加密JSON数据传输的方案
我来帮你梳理下这个问题的解决方案,其实核心就是「加密序列化数据」+「安全传输」+「解密反序列化」这几个环节,结合ASP.NET MVC的特性,给你一套可落地的方案:
一、先确定加密方案:用对称加密(AES)最合适
因为两个站点是你可控的,共享密钥的对称加密效率高、实现简单。注意两个关键点:
- 密钥要单独存储(比如Web.config的
<appSettings>或者密钥管理服务),绝对不能硬编码到代码里! - 加密时一定要搭配初始化向量(IV),不能固定IV,否则加密安全性会大打折扣。
站点A的加密代码示例
先把你的auth对象序列化成JSON,再用AES加密:
using System; using System.Security.Cryptography; using System.Text; using Newtonsoft.Json; // 也可以用.NET内置的System.Text.Json public class EncryptionHelper { // 从配置读取密钥和IV(示例用字节数组,实际要从安全存储读取) private static readonly byte[] _key = Encoding.UTF8.GetBytes(ConfigurationManager.AppSettings["EncryptionKey"]); private static readonly byte[] _iv = Encoding.UTF8.GetBytes(ConfigurationManager.AppSettings["EncryptionIV"]); public static string Encrypt(string plainText) { using (Aes aesAlg = Aes.Create()) { aesAlg.Key = _key; aesAlg.IV = _iv; ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); using (MemoryStream msEncrypt = new MemoryStream()) { using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) { using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) { swEncrypt.Write(plainText); } return Convert.ToBase64String(msEncrypt.ToArray()); } } } } } // 在站点A的Controller里生成加密数据 public ActionResult RedirectToSiteB() { var auth = new { name = "John", age = "20", data = "abc" }; string jsonAuth = JsonConvert.SerializeObject(auth); string encryptedData = EncryptionHelper.Encrypt(jsonAuth); // 下面选择具体的传输方式 }
二、数据传输的两种实现方式
方式1:POST请求(推荐,适合数据量较大或更安全的场景)
因为点击链接默认是GET,所以可以做一个隐藏表单,点击链接时触发表单提交:
站点A的视图(比如Redirect.cshtml):
<a href="#" id="redirectBtn">跳转到站点B</a> <form id="transferForm" action="https://站点B域名/Home/ReceiveData" method="post"> @Html.Hidden("EncryptedData", ViewBag.EncryptedData) </form> <script> document.getElementById('redirectBtn').addEventListener('click', function(e) { e.preventDefault(); document.getElementById('transferForm').submit(); }); </script>
站点A的Controller传递加密数据到视图:
public ActionResult RedirectToSiteB() { // 生成encryptedData的代码同上 ViewBag.EncryptedData = encryptedData; return View(); }
方式2:GET请求(适合数据量极小的情况)
把加密后的Base64字符串作为QueryString参数传递,注意URL长度限制(不同浏览器/服务器略有不同,一般建议不超过2000字符):
站点A的Controller里生成跳转URL:
public ActionResult RedirectToSiteB() { // 生成encryptedData的代码同上 string targetUrl = $"https://站点B域名/Home/ReceiveData?data={Uri.EscapeDataString(encryptedData)}"; return Redirect(targetUrl); }
三、站点B的接收与解密逻辑
站点B需要先接收加密数据,再解密反序列化为对象,注意必须和站点A使用完全相同的密钥和IV!
解密工具类
public class DecryptionHelper { private static readonly byte[] _key = Encoding.UTF8.GetBytes(ConfigurationManager.AppSettings["EncryptionKey"]); private static readonly byte[] _iv = Encoding.UTF8.GetBytes(ConfigurationManager.AppSettings["EncryptionIV"]); public static string Decrypt(string cipherText) { using (Aes aesAlg = Aes.Create()) { aesAlg.Key = _key; aesAlg.IV = _iv; ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV); using (MemoryStream msDecrypt = new MemoryStream(Convert.FromBase64String(cipherText))) { using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) { using (StreamReader srDecrypt = new StreamReader(csDecrypt)) { return srDecrypt.ReadToEnd(); } } } } } }
站点B的Action接收数据
处理POST请求的Action:
[HttpPost] public ActionResult ReceiveData(string EncryptedData) { try { string jsonAuth = DecryptionHelper.Decrypt(EncryptedData); var auth = JsonConvert.DeserializeObject<dynamic>(jsonAuth); // 这里就可以读取auth.name、auth.age等数据了 ViewBag.AuthData = auth; return View(); } catch (Exception ex) { // 处理解密失败的情况,比如数据篡改、密钥不匹配 return View("Error"); } }
处理GET请求的Action:
public ActionResult ReceiveData(string data) { try { string decodedData = Uri.UnescapeDataString(data); string jsonAuth = DecryptionHelper.Decrypt(decodedData); var auth = JsonConvert.DeserializeObject<dynamic>(jsonAuth); ViewBag.AuthData = auth; return View(); } catch (Exception ex) { return View("Error"); } }
四、额外的安全建议
- 一定要用HTTPS:不管是POST还是GET,防止数据在传输过程中被窃听。
- 添加数据完整性验证:可以在加密前给JSON数据加一个HMAC签名,站点B解密后先验证签名,确保数据没被篡改。
- 限制加密数据的有效期:可以在auth对象里加一个
expireTime字段,站点B接收后先检查是否过期,防止重放攻击。 - 密钥定期轮换:不要一直用同一个密钥,定期更换密钥提升安全性。
内容的提问来源于stack exchange,提问作者LuxGameDesign
相关产品推荐
相关产品推荐

