V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
iqingqian
V2EX  ›  Go 编程语言

gin 对于请求参数解密处理的优雅实现

  •  
  •   iqingqian · 2021-03-10 17:07:32 +08:00 · 3012 次点击
    这是一个创建于 1141 天前的主题,其中的信息可能已经有所发展或是发生改变。

    本人要使用 gin 框架写 API 供安卓端调用,迫于安全,客户端会使用 AES 对每个字段进行加密传输,那么服务端这边有没有办法用中间件统一解密,不影响业务使用 ctx.PostForm("xxx")获取字段解密后的值? 或者有没有其他更优雅的实现?

    19 条回复    2021-03-22 09:08:17 +08:00
    demobin
        1
    demobin  
       2021-03-10 17:09:46 +08:00   ❤️ 1
    在 gateway 做
    keepeye
        2
    keepeye  
       2021-03-10 17:11:34 +08:00   ❤️ 2
    啥优雅不优雅的,自己写个方法间接调用 ctx.PostForm 并解密
    kiripeng
        3
    kiripeng  
       2021-03-10 17:18:55 +08:00   ❤️ 1
    一种就是直接用中间件函数把 body 里的 json 每个字段遍历后解密丢回去 body 就行了,然后 用 shouldbind 。
    另一种就是把 shouldbind 和解密的反射函数给封装起来就行了,这样结构体的就得到的是解密后的,当然你要考虑实现的话支持切片的问题就行了把。
    hxndg
        4
    hxndg  
       2021-03-10 17:20:55 +08:00   ❤️ 2
    讲道理,这个是不是应该在别的层做?
    直接 TLS 加密一次?
    iqingqian
        5
    iqingqian  
    OP
       2021-03-10 17:24:12 +08:00
    @kiripeng 感谢,第一种方式,遍历解密后怎么丢回 body,有支持的方法吗?
    kiripeng
        6
    kiripeng  
       2021-03-10 17:31:52 +08:00   ❤️ 1
    @iqingqian
    if c.Request.Body != nil {
    bodyBytes, _ = ioutil.ReadAll(c.Request.Body)
    }
    //解密
    // 复用
    c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))
    xkeyideal
        7
    xkeyideal  
       2021-03-10 17:32:10 +08:00   ❤️ 1
    单纯从技术上来说,这种加密方式,还不如设计一种私有的数据传输协议,统一使用 body 传参,不用考虑参数是 query, form, body 了。
    对于现有的加密方式,即使用中间件来做也会导致后期代码维护性的问题,因为 API 有很多,每个 API 的传参都不一样,难道为每个 API 或每类 API 或特定需要加密的字段写一个中间件?后续需求变动,导致某 API 不能再归为此类又需要改。
    MidGap
        8
    MidGap  
       2021-03-10 17:32:32 +08:00   ❤️ 1
    gin 每个路由的 handle 可以填多个的,gin.GET("/xxx",handel1,handle2) handle1 就是解密的方法 或者 前面搞个 gin.Use(handle1),但是这样就所有的接口都要解密了,前种方法可以在需要的地方解密,当然第二种方法也能搞个白名单不解密
    iqingqian
        9
    iqingqian  
    OP
       2021-03-10 17:56:23 +08:00
    @kiripeng 感谢
    writesome6
        10
    writesome6  
       2021-03-10 18:17:35 +08:00
    这样?

    ```golang

    gin.New().Use(func(c *gin.Context) {
    c.Request.ParseForm()
    encrypetData := c.Request.PostForm.Get("encrypetData")
    c.Request.PostForm = Decrypet(encrypetData)
    c.Next()
    })
    ```
    lewinlan
        11
    lewinlan  
       2021-03-10 19:45:01 +08:00 via Android
    gin 自己的中间件设计还不够优雅吗?
    ratazzi
        12
    ratazzi  
       2021-03-10 20:03:44 +08:00 via iPhone
    好好的 TLS 为啥不用
    asAnotherJack
        13
    asAnotherJack  
       2021-03-10 20:07:28 +08:00
    middleware ?
    Jirajine
        14
    Jirajine  
       2021-03-10 20:25:43 +08:00 via Android   ❤️ 1
    直接 tls 不就行了,为啥要自己再加密?怕 mitm 的话配上 mtls 和 ssl pinning 。
    FucUrFrd
        15
    FucUrFrd  
       2021-03-10 23:25:17 +08:00 via Android
    不要每个字段加密,对 json body 加密
    qoras
        16
    qoras  
       2021-03-10 23:28:54 +08:00
    直接 TLS 就行了啊, 怕爬就加个参数 normalize, 不符合的直接在 nginx 层 ban 掉
    liyaojian
        17
    liyaojian  
       2021-03-11 00:07:34 +08:00 via iPhone
    @qoras #16 normalize 什么意思?
    cominghome
        18
    cominghome  
       2021-03-22 09:05:48 +08:00
    客户端会使用 AES 对每个字段进行加密传输

    同意#7 楼的,直接对整个 body 加密,网关解密后再丢给后端,0 侵入
    cominghome
        19
    cominghome  
       2021-03-22 09:08:17 +08:00
    @Jirajine
    @qoras

    显然不是 TLS 的问题。这种事我们公司也有在做,主要目的是针对黑产(至少提高了门槛)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3606 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 05:01 · PVG 13:01 · LAX 22:01 · JFK 01:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.