【问题标题】:How to add custom encryption/decryption in asp.net core middleware?如何在 asp.net 核心中间件中添加自定义加密/解密?
【发布时间】:2021-10-09 00:01:09
【问题描述】:

我想在我的 asp.net 核心应用程序中有一个自定义中间件,我可以在其中解密即将到来的请求,并在处理或完成一些工作后加密响应。

例如:如果客户端发送一个 msg "Hello server",并且它是从客户端本身加密的,当在服务器上接收时,自定义中间件会对其进行解密并进一步传递给控制器​​以处理数据。服务器回复“hello client”,自定义中间件对数据进行加密。

我知道中间件是如何工作的,但我找不到任何参考如何在我的应用程序中使用它。我有使用公钥和私钥的 RSA 加密,但我不知道如何在中间件中实现它。在中间件中,在实现IMiddleware接口时,在Invoke函数中传入了httpcontext。

我在互联网上找到的只是Response.WriteAsync() 示例。我明白这与HttpContext 类有关。

为简单起见,使用Encrypt()Decrypt(),它们可以使用所需的参数以在中间件中使用。一般中间件调用函数如下。任何帮助将不胜感激。

public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
   //do decryption
   await next(context);
   //do encryption
}

【问题讨论】:

  • 为什么不允许 Web 服务器使用 TLS 执行此操作?
  • 没有要求是有自己的自定义加密/解密。而且我也不知道什么以及如何实现 TLS。看看我是这个中间件概念和实现的新手。
  • actionfilter怎么样?
  • @TinyWang 感谢您的意见。不过我有一个问题,如果请求中有一些模型,它会起作用吗?假设我从客户端发送用户对象,它是一个加密的 json 对象,并在我的服务器上解密它以取回用户对象。并在处理后以加密方式发送响应。相同的中间件也将在客户端。我找到了link,我正在考虑加密和解密请求/响应正文。如果你能帮我解决这个问题。
  • 感谢您的回复,但我不确定我是否在某些地方误解了。我已经更新了我的帖子,请参阅下面的详细信息。

标签: asp.net-core asp.net-web-api encryption httpcontext asp.net-core-middleware


【解决方案1】:

我写了一个demo来实现“过滤器”

using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace CustomActionFilter.Filter
{
    public class MySampleActionFilter : IActionFilter
    {
        public void OnActionExecuting(ActionExecutingContext context)
        {
            var secret = context.HttpContext.Request.Form["secret"].ToString();
            
            string privateKey = "MIICxxxxxxxxxxxxxxxxZg==";
            var privateKeyBits = Convert.FromBase64String(privateKey);
            RSA rsa = RSA.Create();
            var rsaParameters = new RSAParameters();
            BinaryReader binr = new BinaryReader(new MemoryStream(privateKeyBits));
            byte bt = 0;
            ushort twobytes = 0;
            twobytes = binr.ReadUInt16();
            if (twobytes == 0x8130)
                binr.ReadByte();
            else if (twobytes == 0x8230)
                binr.ReadInt16();
            else
                throw new Exception("Unexpected value read binr.ReadUInt16()");

            twobytes = binr.ReadUInt16();
            if (twobytes != 0x0102)
                throw new Exception("Unexpected version");

            bt = binr.ReadByte();
            if (bt != 0x00)
                throw new Exception("Unexpected value read binr.ReadByte()");
            rsaParameters.Modulus = binr.ReadBytes(GetIntegerSize(binr));
            rsaParameters.Exponent = binr.ReadBytes(GetIntegerSize(binr));
            rsaParameters.D = binr.ReadBytes(GetIntegerSize(binr));
            rsaParameters.P = binr.ReadBytes(GetIntegerSize(binr));
            rsaParameters.Q = binr.ReadBytes(GetIntegerSize(binr));
            rsaParameters.DP = binr.ReadBytes(GetIntegerSize(binr));
            rsaParameters.DQ = binr.ReadBytes(GetIntegerSize(binr));
            rsaParameters.InverseQ = binr.ReadBytes(GetIntegerSize(binr));

            rsa.ImportParameters(rsaParameters);
            var temp = Encoding.UTF8.GetString(rsa.Decrypt(Convert.FromBase64String(secret), RSAEncryptionPadding.Pkcs1));
            //JObject json = JObject.Parse(temp);
            context.ActionArguments["secret"] = temp;
        }

        public void OnActionExecuted(ActionExecutedContext context)
        {
            var res = context.Result;
            //encrypt code 
        }


        private int GetIntegerSize(BinaryReader binr)
        {
            byte bt = 0;
            int count = 0;
            bt = binr.ReadByte();
            if (bt != 0x02)
                return 0;
            bt = binr.ReadByte();

            if (bt == 0x81)
                count = binr.ReadByte();
            else
            if (bt == 0x82)
            {
                var highbyte = binr.ReadByte();
                var lowbyte = binr.ReadByte();
                byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
                count = BitConverter.ToInt32(modint, 0);
            }
            else
            {
                count = bt;
            }

            while (binr.ReadByte() == 0x00)
            {
                count -= 1;
            }
            binr.BaseStream.Seek(-1, SeekOrigin.Current);
            return count;
        }

    }
}

并在startup.cs中设置DI

public void ConfigureServices(IServiceCollection services)
        {
            //services.AddScoped<MySampleActionFilter>();
            services.AddControllersWithViews();
            services.AddControllers(config =>
            {
                config.Filters.Add<MySampleActionFilter>();
            });
        }

我的看法:

@{
    ViewData["Title"] = "Home Page";
}

<button id="test">send</button>
<script src="https://cdn.bootcdn.net/ajax/libs/jsencrypt/3.2.1/jsencrypt.min.js"></script>
<script>

    var user = {
        "age": 18,
        "name": "tiny"
    };

    var public_key = "MIGfMA0GCxxxxxxxxxDAQAB";
    var private_key = "MIICWwIxxxxxxxxxlRbEbsDVZg==";

    var encrypt = new JSEncrypt();
    encrypt.setPublicKey(public_key);
    var encrypted = encrypt.encrypt(JSON.stringify(user));
    console.log(encrypted);

    var decrypt = new JSEncrypt();
    decrypt.setPrivateKey(private_key);
    var uncrypted = decrypt.decrypt(encrypted);
    console.log(uncrypted);

    $('#test').click(function () {
        var user = {
            "age": 18,
            "name": "tiny"
        };
        $.ajax({
            url: "https://localhost:44369/hello",
            type: "post",
            data: {
                secret: encrypted
            },
            success: function (data) {
                alert(data);
            }
        })
    });
</script>

我的控制器操作:

[HttpPost]
[ServiceFilter(typeof(MySampleActionFilter))]
public JsonResult Index(string secret)
{
    User json12 = JsonConvert.DeserializeObject<User>(secret);
    User res = new User
    {
        age = 0,
        name = "zero"
    };
    return Json(res);
}

测试结果:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-06
    • 2021-09-27
    • 1970-01-01
    • 2011-01-10
    • 2011-05-14
    • 1970-01-01
    相关资源
    最近更新 更多