李伟乐 2 years ago
parent a203ac5387
commit d048ce9e2a
  1. 0
      app.log
  2. 1
      go.mod
  3. 2
      go.sum
  4. 70
      pkg/jwts/jwts.go
  5. 104
      pkg/xaes/xaes.go
  6. 14
      pkg/xbase64/xbase64.go
  7. 85
      pkg/xtime/xtoken/xtoken.go

@ -5,6 +5,7 @@ go 1.18
require (
git.diulo.com/mogfee/go-common v0.0.0-20230301071202-cc79129d6a24
github.com/PuerkitoBio/goquery v1.8.1
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/envoyproxy/protoc-gen-validate v0.1.0
github.com/gin-gonic/gin v1.9.0
github.com/go-playground/form v3.1.4+incompatible

@ -17,6 +17,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=

@ -0,0 +1,70 @@
package jwts
import (
"crypto/ecdsa"
"crypto/elliptic"
"fmt"
"github.com/dgrijalva/jwt-go"
"github.com/pkg/errors"
"math/big"
)
var (
//ES256 keys
ECDSAKeyD = "7A429E82FF619D38CC8071111988FFA75625DD83B22E9EBEC29F17BFA7BF3A03"
ECDSAKeyX = "76E93569AB21A614BCD581858D0066C8ED611DEFEEA2821CC43EC9E08948A151"
ECDSAKeyY = "61BB8B7EF5333E2E87CDE6DF522BE6BF253C637768F9FA8D9EDCAB270E09B43C"
)
// 获取token数据
func JWTGetMapString(map1 jwt.Claims) (string, error) {
keyD := new(big.Int)
keyX := new(big.Int)
keyY := new(big.Int)
keyD.SetString(ECDSAKeyD, 16)
keyX.SetString(ECDSAKeyX, 16)
keyY.SetString(ECDSAKeyY, 16)
publicKey := ecdsa.PublicKey{
Curve: elliptic.P256(),
X: keyX,
Y: keyY,
}
privateKey := ecdsa.PrivateKey{D: keyD, PublicKey: publicKey}
tokenJwt := jwt.NewWithClaims(jwt.SigningMethodES256, map1)
if tokenString, err := tokenJwt.SignedString(&privateKey); err != nil {
return "", err
} else {
return tokenString, nil
}
}
// 解析jwt数据
func JWTGetStringMap(jwtString string) (map[string]interface{}, error) {
keyX := new(big.Int)
keyY := new(big.Int)
keyX.SetString(ECDSAKeyX, 16)
keyY.SetString(ECDSAKeyY, 16)
publickKey := ecdsa.PublicKey{
Curve: elliptic.P256(),
X: keyX,
Y: keyY,
}
jwtToken, err := jwt.Parse(jwtString, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodECDSA); !ok {
return nil, errors.New(fmt.Sprintf("json 解析失败:%+v", token))
}
return &publickKey, nil
})
if err == nil {
if claims, ok := jwtToken.Claims.(jwt.MapClaims); ok {
return claims, nil
}
}
return nil, errors.New(fmt.Sprintf("json 解析失败:%v", jwtString))
}

@ -0,0 +1,104 @@
package xaes
import (
"bytes"
"crypto/aes"
"crypto/cipher"
)
//#;AES加解密使用 长度 16, 24, 32
//const aesKey = "sfe023f_9fd&fwfl"
////加密字符串
//func AesEncrypt(hstring string) (string, error) {
// if result, err := aesEncrypt([]byte(hstring), []byte(aesKey)); err != nil {
// return "", err
// } else {
// return base64.StdEncoding.EncodeToString(result), nil
// }
//}
//
////解密字符串
//func AesDecrypt(hstring string) (string, error) {
// if bye, err := base64.StdEncoding.DecodeString(hstring); err != nil {
// return "", err
// } else {
// if result, err := aesDecrypt(bye, []byte(aesKey)); err != nil {
// return "", err
// } else {
// return string(result), nil
// }
// }
//}
//func AESTestCode() {
// // AES-128。key长度:16, 24, 32 bytes 对应 AES-128, AES-192, AES-256
// key := []byte("sfe023f_9fd&fwfl")
// result, err := aesEncrypt([]byte("polaris@studygolang"), key)
// if err != nil {
// panic(err)
// }
// fmt.Println(result)
// a, _ := AesEncrypt("polaris@studygolang")
// aa, _ := base64.StdEncoding.DecodeString(a)
// origData, err := aesDecrypt(aa, key)
// if err != nil {
// panic(err)
// }
// fmt.Println(string(origData))
//}
func Encrypt(origData, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
blockSize := block.BlockSize()
origData = pKCS5Padding(origData, blockSize)
// origData = ZeroPadding(origData, block.BlockSize())
blockMode := cipher.NewCBCEncrypter(block, key[:blockSize])
crypted := make([]byte, len(origData))
// 根据CryptBlocks方法的说明,如下方式初始化crypted也可以
// crypted := origData
blockMode.CryptBlocks(crypted, origData)
return crypted, nil
}
func Decrypt(crypted, 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(crypted))
// origData := crypted
blockMode.CryptBlocks(origData, crypted)
origData = pKCS5UnPadding(origData)
// origData = ZeroUnPadding(origData)
return origData, nil
}
// func zeroPadding(ciphertext []byte, blockSize int) []byte {
// padding := blockSize - len(ciphertext)%blockSize
// padtext := bytes.Repeat([]byte{0}, padding)
// return append(ciphertext, padtext...)
// }
//
// func zeroUnPadding(origData []byte) []byte {
// length := len(origData)
// unpadding := int(origData[length-1])
// return origData[:(length - unpadding)]
// }
func pKCS5Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
func pKCS5UnPadding(origData []byte) []byte {
length := len(origData)
unpadding := int(origData[length-1])
return origData[:(length - unpadding)]
}

@ -0,0 +1,14 @@
package xbase64
import (
b64 "encoding/base64"
)
func Encode(s string) string {
return b64.StdEncoding.EncodeToString([]byte(s))
}
func Decode(s string) (string, error) {
ds, err := b64.StdEncoding.DecodeString(s)
return string(ds), err
}

@ -0,0 +1,85 @@
package xtoken
import (
"context"
"encoding/json"
"errors"
"git.diulo.com/mogfee/protoc-gen-kit/pkg/jwts"
"git.diulo.com/mogfee/protoc-gen-kit/pkg/xaes"
"git.diulo.com/mogfee/protoc-gen-kit/pkg/xbase64"
"github.com/dgrijalva/jwt-go"
"time"
)
const (
// expiredTime 授权结束时间
expiredTime = 7200
tokenKey = "68Tz&xWUW5U$Id45"
)
type TokenInfo struct {
Id int64
Permission []string
}
var tokenExpired = errors.New("token expired")
type tokenStoreInfo struct {
Created int64 `json:"created"`
ExpiredAt int64 `json:"expired_at"`
Id int64 `json:"id"`
Permission []string `json:"permission"`
}
func GetTokenStr(ctx context.Context, info TokenInfo) (string, error) {
ctime := time.Now().Unix()
tokenString, err := jwts.JWTGetMapString(jwt.MapClaims{
"id": info.Id,
"permission": info.Permission,
"created": ctime,
"expired_at": ctime + expiredTime,
})
if err != nil {
return "", err
}
aesString, err := xaes.Encrypt([]byte(tokenString), []byte(tokenKey))
if err != nil {
return "", err
}
return xbase64.Encode(string(aesString)), nil
}
func ParseToken(tokenStr string) (*TokenInfo, error) {
tokenStr, err := xbase64.Decode(tokenStr)
if err != nil {
return nil, err
}
body, err := xaes.Decrypt([]byte(tokenStr), []byte(tokenKey))
if err != nil {
return nil, err
}
mps, err := jwts.JWTGetStringMap(string(body))
if err != nil {
return nil, errors.New("token parse error")
}
b, _ := json.Marshal(mps)
row := tokenStoreInfo{}
if err = json.Unmarshal(b, &row); err != nil {
return nil, err
}
if row.ExpiredAt < time.Now().Unix() || row.Id <= 0 {
return nil, tokenExpired
}
return &TokenInfo{
Id: row.Id,
Permission: row.Permission,
}, nil
}
func IsExpired(err error) bool {
return err == tokenExpired
}
Loading…
Cancel
Save