基于cookire双向加密
# go 基于cookie的双向加密验证标签: gocookie 双向加密
>**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)
//截取切片,删除填充字节,并且返回明文
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 mapFilterHandle
}
//初始化
func NewFilter() *Filter {
return &Filter{
filterMap: make(mapFilterHandle),
}
}
// RegisterFilterUri 注册拦截器
func (f *Filter) RegisterFilterUri(uri string, handler FilterHandle) {
f.filterMap = handler
}
// GetFilterHandle 获取拦截器
func (f *Filter) GetFilterHandle(uri string) FilterHandle {
return f.filterMap
}
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]