广告
返回顶部
首页 > 资讯 > 精选 >.NET API接口数据传输加密怎么实现
  • 206
分享到

.NET API接口数据传输加密怎么实现

2023-07-04 12:07:53 206人浏览 泡泡鱼
摘要

这篇文章主要介绍了.net api接口数据传输加密怎么实现的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇.NET API接口数据传输加密怎么实现文章都会有所收获,下面我们一起来看看吧。硬编码

这篇文章主要介绍了.net api接口数据传输加密怎么实现的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇.NET API接口数据传输加密怎么实现文章都会有所收获,下面我们一起来看看吧。

硬编码方式

最先想到的应该就是硬编码方式,就是哪个接口需要进行传输加密,那么就针对该接口特殊处理:

public class SecurityApiController {...public async Task<Result> UpdateUser([FromBody] SecurityRequest request) {    var requestBody = RsaHelper.Decrypt(privateKey, request.Content);            var user = JSONHelper.Deserialize<UserDto>(requestBody);    await UpdateUserAsync(user);    return new Result(RsaHelper.Encrypt(publicKey, new{ Success=true}));}}

这种方式好处是简单明了,按需编程即可,不会对其它接口造成污染。

一旦这种需求越来越多,我们就会写大量如上的重复性代码;而对于前端而言也是如此,所以当我们需要传输加密乃是最基础的需求时,上面硬编码的方式就显得很不合适了。

这个时候我们可以采用统一入口的方式来实现

统一入口

回顾上面的硬编码方式,其实每个接口处的加解密处理从 SRP 原则上理解,不应该是接口的职责。所以需要把这部分的代码移到一个单独的方法,再加解密之后我们再把该请求调度到具体的接口。

这种方式其实有很多种实现方式,在这里我先说一下我司其中一个 .NET4.5 的项目采取的方式。

其实就是额外提供了一个统一的入口,所有需要传输加密的需求都走这一个接口:如Http://api.example.com/security

public class SecurityController {...public async Task<object> EntryPoint([FromBody] SecurityRequest request) {    var requestBody = RsaHelper.Decrypt(privateKey, request.Content);    var user = jsonHelper.Deserialize<UserDto>(requestBody);    var obj = await DispathRouter(requestBody.Router, user);            return new Result(RsaHelper.Encrypt(publicKey, obj));}public async Task<object> DispathRouter(Router router, object body) {    ...    Type objectCon = typeof(BaseController);            MethodInfo methInfo = objectCon.GetMethod(router.Name);            var resp = (Task<object>)methInfo.Invoke(null, body);            return await resp;}}

很明显这是通过统一入口地址调用并配合反射来实现这种目的。

这种好处如前面所说,统一了调用入口,这样提高了代码复用率,让加解密不再是业务接口的一部分了。同样,这种利用一些不好的点;比如用了反射性能会大打折扣。并且我们过度的进行统一了。我们看到这种方式只能将所有的接口方法都写到 BaseController。所以我司项目的 Controller 部分,会看到大量如下的写法:

// 文件 UserController.cspublic partial class BaseController {...}// 文件 AccountController.cs public partial class BaseController {}// ...

这样势必就会导致一个明显的问题,就是“代码爆炸”。这相当于将所有的业务逻辑全部灌输到一个控制器中,刚开始写的时候方便了,但是后期维护以及交接换人的时候阅读代码是非常痛苦的一个过程。因为在不同的 Controller 文件中势必会重复初始化一些模块,而我们在引用方法的时候 IDE 每次都会显示上千个方法,有时候还不得不查看哪些方法名一样或相近的具体意义。

针对上述代码爆炸的方式还有一种优化,就是将控制器的选择开放给应用端,也就是将方法名和控制器名都作为请求参数暴露给前端,但是这样会加大前端的开发心智负担。

综上所述我是非常不建议采用这种方式的。虽说是很古老的.Net4/4.5 的框架,但是我们还是有其它相对更优雅的实现方式。

中间件

其实我们熟悉了 .netcore 下的 Middleware机制,我们会很容易的在 .netcore 下实现如标题的这种需求:

// .NET Core 版本public class SecuriryTransportMiddleware {    private readonly RequestDelegate _next;    public RequestCultureMiddleware(RequestDelegate next)    {        _next = next;    }        public async Task InvokeAsync(HttpContext context)    {    // request handle        var encryptedBody = context.Request.Body;        var encryptedContent = new StreamReader(encryptedBody).ReadToEnd();        var decryptedBody = RsaHelper.Decrypt(privateKey, encryptedContent);        var originBody = JsonHelper.Deserialize<object>(decryptedBody);                var json = JsonHelper.Serialize(dataSource);        var requestContent = new StrinGContent(json, Encoding.UTF8, "application/json");        stream = await requestContent.ReadAsStreamAsync();        context.Request.Body = stream;                await _next(context);        // response handle        var originContent = new StreamReader(context.Response.Body).ReadToEnd();        var encryptedBody = RsaHelper.Encrypt(privateKey, originContent);        var responseContent = new StringContent(json, Encoding.UTF8, "application/json");        context.Response.Body = await responseContent.ReadAsStreamAsync();        // 或者直接        // await context.Response.WriteAsync(encryptedBody);    }}

为了方便描述,以上代码我省略了必要的校验和异常错误处理

这样有什么好处呢?一个最明显的好处就是解耦了加解密与真正业务需求。对真正的业务代码几乎没有侵略性。其实我认为业务开发能做到这里其实就差不多了,还有其它需求都可以基于这个中间件进行拓展开发。

那么在 .NET Framwork 没有中间件怎么办呢?

其实在 .NET Framwork 框架下 IHttpModule 能和中间件一样能做到这点:

public class SecurityTransportHttpModule : IHttpModule {...public void Init(HttpApplication context) {    ...    context.BeginRequest += ContextBeginRequest;    context.PostRequestHandlerExecute += ContextPostRequestHandlerExecute;}private void ContextBeginRequest(object sender, EventArgs e) {    HttpContext context = ((HttpApplication)sender).Context;    var encryptedBody = context.Request.Body;    ...    context.Request.Body = stream;}private void ContextPostRequestHandlerExecute(object sender, EventArgs e)        {            HttpContext context = ((HttpApplication)sender).Context;            ...            context.Response.Write(encryptedBody)        }}

为什么之前提到这种方案就“差不多”了呢,实际上上面这种方式在某些场景下会显得比较“累赘”。因为无论通过中间件和还是 IHttpModule 都会导致所有请求都会经过它,相当于增加了一个过滤器,如果这时候我要新增一个上传文件接口,那必然也会经过这个处理程序。说的更直接一点,如果碰到那些少数不需要加解密的接口请求那要怎么办呢?

其实上面可以进行拓展处理,比如对特定的请求进行过滤:

if(context.Request.Path.Contains("upload")) {return;}

注意上述代码只是做个 demo 展示,真正还是需要通过如 context.GetRouterData() 获取路由数据进行精准比对。

当类似于这种需求开始变多以后(吐槽:谁知道业务是怎么发展的呢?)原来的中间件的“任务量”开始变得厚重了起来。到时候也会变得难以维护和阅读。

这个时候就是我目前较为满意的解决方案登场了,它就是模型绑定 ModelBinding。

模型绑定

回到需求的开端,不难发现,我们其实要是如何将前端加密后的请求体绑定到我们编写的接口方法中。这里面的过程很复杂,需要解析前端发起的请求,解密之后还要反序列化成目标接口需要的方法参数。而这个过程还要伴随着参数校验,如这个请求是否符合加密格式。而这个过程的一切都是模型绑定要解决的事。我们以 NETCore 版本为例子,讲一下大概的流程;

模型绑定的过程其实就是将请求体的各个字段于具体的 CLR 类型的字段属性进行一一匹配的过程。.NetCore 再程序启动时会默认提供了一些内置的模型绑定器,并开放 IModelBinderProvider 接口允许用户自定义模型绑定器。我们通过查看 mvcCoreMvcOptionsSetup 就清楚看到框架为我们添加 18 个自带的模型绑定器。以及如何调用的方式。

所以接下来我们很容易的可以一葫芦画瓢的照抄下来:

public class SecurityTransportModelBinder : IModelBinder {    ...    public async Task BindModelAsync(ModelBindingContext bindingContext)    {        if (bindingContext == null)        {            throw new ArgumentNullException(nameof(bindingContext));        }        try        {            var request = bindingContext.HttpContext.Request;            var model = await JsonSerializer.DeserializeAsync&lt;SafeDataWrapper&gt;(request.Body, new JsonSerializerOptions            {                PropertyNamingPolicy = JsonNamingPolicy.CamelCase,            });            var decryptContent = RsaHelper.Decrypt(model.Info, privateKey);            var activateModel = JsonSerializer.Deserialize(decryptContent, bindingContext.ModelMetadata.ModelType, new JsonSerializerOptions            {                PropertyNamingPolicy = JsonNamingPolicy.CamelCase,            });            //重新包装            if (activateModel == null)            {                bindingContext.Result = ModelBindingResult.Failed();            }            else            {                bindingContext.Result = ModelBindingResult.Success(activateModel);            }        }        catch (Exception exception)        {            bindingContext.ModelState.TryAddModelError(                bindingContext.ModelName,                exception,                bindingContext.ModelMetadata);        }        _logger.DoneAttemptingToBindModel(bindingContext);        //return Task.CompletedTask;    }}

抄了 ModelBinder 还不行,还要抄 ModelBinderProvider:

public class SecurityTransportModelBinderProvider : IModelBinderProvider{    public IModelBinder GetBinder(ModelBinderProviderContext context)    {        if (context == null)        {            throw new ArgumentNullException(nameof(context));        }        if (context.Metadata.IsComplexType && typeof(IApiEncrypt).IsAssignableFrom(context.Metadata.ModelType))        {            var loggerFactory = context.Services.GetRequiredService<ILoggerFactory>();            var configuration = context.Services.GetRequiredService<IConfiguration>();            return new SecurityTransportModelBinder(loggerFactory, configuration);        }        return null;    }}

这里我做了一个方便我自己的拓展功能,就是显示打了 IApiEncrypt 接口标签的才会正常进行解析绑定。

剩下的就是在 ConfigureService 中添加进去即可:

services.AddControllers(options => {...options.ModelBinderProviders.Insert(0, new SecurityTransportModelBinderProvider());})

这样实现过后,我们就能像使用 FromBody 那样就能按需调用即可:

[HttpPost("security")]public async Task<ResultDto> DemoDecrypt([ModelBinder(typeof(SecurityTransportModelBinder))] OriginBusinessRequest request){    //激活结果...    return await Task.FromResult(WriteSafeData(data, publicKey));}

如果是默认处理加解密也是可以的,直接在对应的请求实体类打上 IApiEncrypt 标签就会自动执行模型绑定

public class UserUpdateRequest: IApiEncrypt {public int UserId { get; set; }public string Phone { get; set; }public string Address { get; set; }...}

这种方案其实也还是有缺点的,从刚刚的使用来看就知道,模型绑定无法解决返回自动加密处理。所以我们不得不在每个接口处写下如 WriteSafeData(data, publicKey) 这种显式加密的代码。

优化的方式也很简单,其实我们可以通过过滤器可以解决,这也是为什么我要加 IApiEncrypt 的原因,因为有了这个就能确定知道这是一个安全传输的请求,进而进行特殊处理。

注意,这不是 .net core 独有的特性,.Net Framework 也有模型绑定器

关于“.NET API接口数据传输加密怎么实现”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“.NET API接口数据传输加密怎么实现”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网精选频道。

--结束END--

本文标题: .NET API接口数据传输加密怎么实现

本文链接: https://www.lsjlt.com/news/344994.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • .NET API接口数据传输加密怎么实现
    这篇文章主要介绍了.NET API接口数据传输加密怎么实现的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇.NET API接口数据传输加密怎么实现文章都会有所收获,下面我们一起来看看吧。硬编码...
    99+
    2023-07-04
  • .NET API 接口数据传输加密最佳实践记录
    目录硬编码方式统一入口中间件模型绑定总结参考资料我们在做 Api 接口时,相信一定会有接触到要给传输的请求 body 的内容进行加密传输。其目的就是为了防止一些敏感的内容直接被 UI...
    99+
    2022-11-13
    .net api接口数据传输加密 api接口数据传输加密
  • api接口数据怎么加密
    使用AES加密算法对api接口数据进行加密,具体方法如下:...
    99+
    2022-10-06
  • vue数据传输怎么加密
    今天小编给大家分享一下vue数据传输怎么加密的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。1.首先,在vue项目中使用yar...
    99+
    2023-07-04
  • FTP传输数据怎么加密
    利用vsftp对FTP传输数据进行加密的方法首先,在计算机中创建一个FTP用户;user -d /ftp_www -s /sbin/nologin mvpbangecho "123123" | passwd mvpbang --stdinc...
    99+
    2022-10-17
  • api数据接口为什么要加密
    api数据接口需要进行加密的原因以下几点防止伪装攻击在公共网络环境中,防止第三方有意或恶意的调用api数据接口。防止篡改攻击在公共网络环境中,防止请求头、查询字符串、内容在传输过程中被修改。防止重放攻击在公共网络环境中,防止请求被截获后被重...
    99+
    2022-10-23
  • Node怎么实现前后端数据传输加密解密
    今天小编给大家分享一下Node怎么实现前后端数据传输加密解密的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一...
    99+
    2022-10-19
  • 怎么实现 Spring Boot 接口参数加密解密
    本篇内容主要讲解“怎么实现 Spring Boot 接口参数加密解密”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么实现 Spring Boot 接口参数加密解密”吧!加密解密本身并不是难事,...
    99+
    2023-06-17
  • h5如何实现数据安全加密传输
    h5利用api接口实现数据加密传输,具体方法如下:function CurlPost($url, $param = null, $timeout = 10){//初始化curl$curl = curl_init();curl_setopt(...
    99+
    2022-10-12
  • 前后端传输数据加密怎么做
    使用base64加密实现前后端数据加密传输的方法具体方法如下:var keyStr = "ABCDEFGHIJKLMNOP"+"QRSTUVWXYZabcdef"+"ghijklmnopqrstuv"+"wxyz0123456789+/="...
    99+
    2022-10-17
  • PHP加密解密函数实现数据传输的安全保护功能
    PHP加密解密函数实现数据传输的安全保护功能随着互联网的快速发展和应用的普及,数据的安全性问题变得尤为重要。很多网站和应用程序需要在客户端和服务器之间传输敏感数据,如用户密码、银行账户信息等,为了保护这些数据的安全,一种可行的方法是使用加密...
    99+
    2023-11-20
    数据传输 安全保护 PHP加密解密函数
  • 前端怎么对接口数据进行加密
    在前端中使用AES对接口数据进行加密的方法前端代码如下:var aesUtil = {//获取key,genKey : function (length = 16) {let random = "ABCDEFGHIJKLMNOPQRSTUV...
    99+
    2022-10-13
  • 微信小程序接口加密怎么实现
    本篇内容主要讲解“微信小程序接口加密怎么实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“微信小程序接口加密怎么实现”吧!场景小程序请求的所有接口参数必须加密,后台返回数据也需要加密,并且增加T...
    99+
    2023-06-26
  • Node.Js怎么实现sendfile数据传输
    本篇内容主要讲解“Node.Js怎么实现sendfile数据传输”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Node.Js怎么实现sendfile数据传输”吧!首先我们看一下sendfile的...
    99+
    2023-07-04
  • 利用PHP加密函数实现数据传输的安全保护功能
    利用PHP加密函数实现数据传输的安全保护功能随着互联网的发展和普及,数据传输的安全性成为了一个极其重要的问题。无论是在网上购物、银行转账还是公司内部通信,都需要确保数据的安全传输。为了解决这个问题,开发人员可以利用PHP的加密函数来实现数据...
    99+
    2023-11-20
    PHP 数据传输 加密函数
  • postman数据加解密实现APP登入接口模拟请求
    目录主要使用到的Postman功能数据加解密各种参数设置真正发送的数据:请求处理脚本[Pro-request Script]响应处理脚本[Tests]结果的样子主要使用到的Postm...
    99+
    2022-11-12
  • ASP编程算法中,如何使用HTTP接口实现数据传输?
    ASP(Active Server Pages)是一种基于Microsoft的服务器端脚本技术,它可以用来开发动态网站、Web应用程序和Web服务。在ASP编程中,HTTP接口是一种非常重要的数据传输方式。通过HTTP接口,ASP程序可以...
    99+
    2023-11-09
    编程算法 http 接口
  • Python文件接口和二维码:如何实现高效数据传输?
    在日常工作中,我们经常需要将文件或数据传输给其他人或系统。而Python提供了许多方法来实现数据传输,其中文件接口和二维码是两种非常有效的方式。本文将介绍如何使用Python文件接口和二维码实现高效数据传输。 一、文件接口 文件接口是一种...
    99+
    2023-10-09
    文件 接口 二维码
  • 怎么用JS实现Base64编码和MD5加密完成快递鸟API接口调用
    本篇内容主要讲解“怎么用JS实现Base64编码和MD5加密完成快递鸟API接口调用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么用JS实现Base64编码...
    99+
    2022-10-19
  • 如何在ASP存储接口shell中实现数据加密功能?
    ASP是一种被广泛使用的服务器端脚本语言,常用于动态网站的开发。在ASP存储接口shell中,为了保证数据的安全性,我们通常需要对数据进行加密。本篇文章将介绍如何在ASP存储接口shell中实现数据加密功能。 一、加密方式的选择 在ASP存...
    99+
    2023-11-06
    存储 接口 shell
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作