设为首页 收藏本站
查看: 1729|回复: 0

[经验分享] 基于cookire双向加密

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2022-4-1 17:24:39 | 显示全部楼层 |阅读模式
# go 基于cookie的双向加密验证
标签: go  cookie 双向加密



>**cookie 双向加密验证**

```
//高级加密标准 (aes)
16,24,32位字符串的话,分别对应AES-128,AES-192,AES-256 加密方法
//16,24,32位字符串的话,分别对应AES-128,AES-192,AES-256 加密方法
//key不能泄露
var PwdKey = []byte("DIS**#KKKDJJSKDI")

// PKCS7Padding PKCS7 填充模式
func PKCS7Padding(ciphertext []byte, blockSize int) []byte {
        padding := blockSize - len(ciphertext)%blockSize
        //Repeat()函数的功能是把切片[]byte{byte(padding)}复制padding个,然后合并成新的字节切片返回
        padtext := bytes.Repeat([]byte{byte(padding)}, padding)
        return append(ciphertext, padtext...)
}

// PKCS7UnPadding 填充的反向操作,删除填充字符串
func PKCS7UnPadding(origData []byte) ([]byte, error) {
        //获取数据长度
        length := len(origData)
        if length == 0 {
                return nil, errors.New("加密字符串错误!")
        } else {
                //获取填充字符串长度
                unpadding := int(origData[length-1])
                //截取切片,删除填充字节,并且返回明文
                return origData[:(length - unpadding)], nil
        }
}

// AesEcrypt 实现加密
func AesEcrypt(origData []byte, key []byte) ([]byte, error) {
        //创建加密算法实例
        block, err := aes.NewCipher(key)
        if err != nil {
                return nil, err
        }
        //获取块的大小
        blockSize := block.BlockSize()
        //对数据进行填充,让数据长度满足需求
        origData = PKCS7Padding(origData, blockSize)
        //采用AES加密方法中CBC加密模式
        blocMode := cipher.NewCBCEncrypter(block, key[:blockSize])
        crypted := make([]byte, len(origData))
        //执行加密
        blocMode.CryptBlocks(crypted, origData)
        return crypted, nil
}

// AesDeCrypt 实现解密
func AesDeCrypt(cypted []byte, key []byte) ([]byte, error) {
        //创建加密算法实例
        block, err := aes.NewCipher(key)
        if err != nil {
                return nil, err
        }
        //获取块大小
        blockSize := block.BlockSize()
        //创建加密客户端实例
        blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])
        origData := make([]byte, len(cypted))
        //这个函数也可以用来解密
        blockMode.CryptBlocks(origData, cypted)
        //去除填充字符串
        origData, err = PKCS7UnPadding(origData)
        if err != nil {
                return nil, err
        }
        return origData, err
}

//加密base64
func EnPwdCode(pwd []byte) (string, error) {
        result, err := AesEcrypt(pwd, PwdKey)
        if err != nil {
                return "", err
        }
        return base64.StdEncoding.EncodeToString(result), err
}

//解密
func DePwdCode(pwd string) ([]byte, error) {
        //解密base64字符串
        pwdByte, err := base64.StdEncoding.DecodeString(pwd)
        if err != nil {
                return nil, err
        }
        //执行AES解密
        return AesDeCrypt(pwdByte, PwdKey)

}


```

>go 拦截器

```
package help

import "net/http"

// FilterHandle 声明一个新的数据类型
type FilterHandle func(rw http.ResponseWriter, r *http.Request) error

// Filter 拦截器结构体
type Filter struct {
        //用来存需要拦截的url
        filterMap map[string]FilterHandle
}

//初始化
func NewFilter() *Filter {
        return &Filter{
                filterMap: make(map[string]FilterHandle),
        }
}

// RegisterFilterUri 注册拦截器
func (f *Filter) RegisterFilterUri(uri string, handler FilterHandle) {
        f.filterMap[uri] = handler
}

// GetFilterHandle 获取拦截器
func (f *Filter) GetFilterHandle(uri string) FilterHandle {
        return f.filterMap[uri]
}

type WebHandle func(rw http.ResponseWriter, r *http.Request)

func (f *Filter) Handle(webHandle WebHandle) func(rw http.ResponseWriter, r *http.Request) {
        return func(rw http.ResponseWriter, r *http.Request) {
                for path, handle := range f.filterMap {
                        if path == r.RequestURI {
                                err := handle(rw, r)
                                if err != nil {
                                        rw.Write([]byte(err.Error()))
                                        return
                                }
                                break
                        }

                }
                //执行正常注册的函数
                webHandle(rw, r)
        }
}
```
>实现拦截器
```
package main

import (
        "errors"
        "fmt"
        "net/http"
        "order/encrypt"
        "order/help"
)

func Check(rw http.ResponseWriter, r *http.Request) {
        fmt.Println("Check")
}
func Auth(rw http.ResponseWriter, r *http.Request) error {
        //添加基于cookie的权限验证
        err := CheckUserInfo(r)
        if err != nil {
                return err
        }
        return nil
}

//检查用户信息
func CheckUserInfo(r *http.Request) error {
        uidCookie, err := r.Cookie("uid")
        if err != nil {
                return errors.New("用户UID cookie 获取失败")
        }
        signCookie, err := r.Cookie("sign")
        if err != nil {
                return errors.New("用户加密cookie 获取失败")
        }
        //对加密信息进行解密
        signByte, err := encrypt.DePwdCode(signCookie.Value)
        fmt.Println("sign加密串", string(signByte))
        fmt.Println("uid", uidCookie.Value)
        ok := CheckCookie(uidCookie.Value, string(signByte))
        if !ok {
                return errors.New("身份校验失败")
        }
        return nil
}

//检查cookie是否一致
func CheckCookie(checkStr string, signStr string) bool {
        if checkStr == signStr {
                return true
        }
        return false
}
func main() {
        filter := help.NewFilter()
        filter.RegisterFilterUri("/check", Auth)
        http.HandleFunc("/check", filter.Handle(Check))
        http.ListenAndServe(":9999", nil)
}
```



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-1002212-1-1.html 上篇帖子: 求51reboot golang实战视频课程 下篇帖子: 没有了
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表