如何在 .NET Core WebAPI 和 Javascript 应用程序中安全地发送/接收密钥参数

目录

描述

[JavaScript 中的加密](#JavaScript 中的加密)

[C# 中的解密](# 中的解密)

结论


如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。

描述

在 API 中,通常会使用一些标识符密钥来识别用户详细信息并据此处理数据。这些信息通常从客户端的查询参数、请求头或路由路径中获取。
然而,这些 API 会在安全审计过程中被拒绝,因为它们暴露了用户数据,并且存在不安全的对象引用漏洞,攻击者可以通过修改这些 API 参数来恶意利用该漏洞获取其他用户的信息。
有很多方法可以解决这个安全问题,但本教程将解释如何通过将这些参数加密成一个密钥并将其放在请求头中来解决这个问题。我还会解释如何使用 .NET Core API 中的中间件在 API 级别处理这个问题。加密在客户端应用程序中使用 JavaScript 完成,解密在 API 级别使用 C# 完成。
我使用了 AES 密钥加密算法来实现加密和解密。

假设我们有一个薪资 API,其中 employeeid 作为参数。

api/salaries/getbyemployeeid?employeeid=1031

在这个 API 中,我们公开了一个重要的关键标识符 employeeid,因此它被暴露了,因为任何拥有基本身份验证的人都可以查看其他员工的详细信息。为了避免这种情况,我们首先将删除查询参数。

api/salaries/getbyemployeeid

接下来,我们将使用 AES 加密生成一个加密密钥,然后将该密钥作为标头发送。

JavaScript 中的加密

安装软件包npm install crypto-js

const CryptoJS = require('crypto-js');

function Encrypt(str) {

var KEY = "12345678900000001234567890000000";//32 bit

var IV = "1234567890000000";//16 bits

var key = CryptoJS.enc.Utf8.parse(KEY);

var iv = CryptoJS.enc.Utf8.parse(IV);

var encrypted = '';

var srcs = CryptoJS.enc.Utf8.parse(str);

encrypted = CryptoJS.AES.encrypt(srcs, key, {

iv: iv,

mode: CryptoJS.mode.CBC,

padding: CryptoJS.pad.Pkcs7

});

return encrypted.ciphertext.toString();

}

var encryptedEmployeeId = Encrypt("1031");

console.log(encryptedEmployeeId);

//result would be EF082204BF6F804099396A96CC7733F4

C# 中的解密

public class EncryptDecrypt

{

public static string AESDecryption(string input)

{

string AES_IV = "1234567890000000";//16 bits

string key = "12345678900000001234567890000000"; //32 bits

byte\[\] inputBytes = HexStringToByteArray(input);

byte\[\] keyBytes = Encoding.UTF8.GetBytes(key.Substring(0, 32));

using AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider();

aesAlg.Key = keyBytes;

aesAlg.IV = Encoding.UTF8.GetBytes(AES_IV.Substring(0, 16));

ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);

using MemoryStream msEncrypt = new MemoryStream(inputBytes);

using CryptoStream csEncrypt = new CryptoStream(msEncrypt, decryptor, CryptoStreamMode.Read);

using StreamReader srEncrypt = new StreamReader(csEncrypt);

return srEncrypt.ReadToEnd();

}

private static byte\[\] HexStringToByteArray(string s)

{

s = s.Replace(" ", "");

byte\[\] buffer = new bytes.Length / 2;

for (int i = 0; i < s.Length; i += 2)

bufferi / 2 = (byte)Convert.ToByte(s.Substring(i, 2), 16);

return buffer;

}

}

**我在请求头中发送了加密参数,**并添加了一个名为 Request-Id 的请求头。
Request-Id : EF082204BF6F804099396A96CC7733F4

添加请求中间件来获取标头值并对其进行解密。

public class RequestMiddleware

{

private readonly RequestDelegate _next;

public RequestMiddleware(RequestDelegate next)

{

_next = next;

}

public async Task Invoke(HttpContext context)

{

if (context.Request.Headers.TryGetValue("Request-Id", out var requestid))

{

var employeeid = EncryptDecrypt.AESDecryption(requestid);

}

await _next(context);

}

}

在其他 API 使用的中间件之前配置该中间件,使其可用并可以保存在静态变量中。

app.UseMiddleware(typeof(RequestMiddleware));

结论

在本教程中,解释了如何在 API 请求的标头中发送基于密钥的加密参数,而不是直接发送,并按照最初所示修改了 API。

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。

相关推荐
Larcher6 小时前
React Router 不只是页面跳转:从 SPA 路由到权限守卫的完整实践
javascript·后端
Larcher6 小时前
大模型为什么每次回答都不一样?一文搞懂 Temperature、Top K 与 Top P
javascript·后端
eric-sjq9 小时前
10 分钟实战:用 0.6B 本地模型生成中文网页(WanlyFrontend + 编译器全流程)
javascript·机器学习·自然语言处理·html
To_OC10 小时前
LC 438 找到所有字母异位词:暴力超时后,我靠滑动窗口一招搞定
javascript·算法·leetcode
kyriewen11 小时前
面试官问"这段逻辑为什么这样写"——我才发现,这半年我写的代码,我自己都解释不了
前端·javascript·面试
一壶浊酒..11 小时前
Scrape Webpack练习
开发语言·javascript·webpack
默_笙15 小时前
⛵ 我用 React + TS 做了个"调色盘",顺便学会了企业级项目的目录架构
前端·javascript
渣波15 小时前
拒绝 Redux 样板代码:Zustand 核心原理与实战进阶指南(基础、异步与切片模式)
前端·javascript
C++、Java和Python的菜鸟15 小时前
第12章 前端Web进阶(Vue工程化+ElementPlus)
前端·javascript·vue.js
妙码生花16 小时前
让各大 AI 整理出来的前端工程命名最简实践(Vue + TS)
前端·javascript·vue.js