155 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			155 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Go
		
	
	
	
| package encipher
 | |
| 
 | |
| import (
 | |
| 	"bytes"
 | |
| 	"crypto/aes"
 | |
| 	"crypto/cipher"
 | |
| 	"encoding/base64"
 | |
| 	"encoding/json"
 | |
| 	"strings"
 | |
| 	"time"
 | |
| 
 | |
| 	"git.apinb.com/bsm-sdk/core/env"
 | |
| 	"git.apinb.com/bsm-sdk/core/errcode"
 | |
| 	"git.apinb.com/bsm-sdk/core/types"
 | |
| 	"git.apinb.com/bsm-sdk/core/vars"
 | |
| )
 | |
| 
 | |
| var (
 | |
| 	certBytes    *types.CertFileBytes = nil
 | |
| 	JwtSecret    []byte
 | |
| 	JwtSecretLen int
 | |
| )
 | |
| 
 | |
| func New(secret string) {
 | |
| 	JwtSecret = []byte(secret)
 | |
| 	JwtSecretLen = len(env.Runtime.JwtSecretKey)
 | |
| }
 | |
| 
 | |
| func GenerateTokenAes(id uint, identity, client, role string, owner any, extend map[string]string) (string, error) {
 | |
| 	if !(JwtSecretLen == 16 || JwtSecretLen == 24 || JwtSecretLen == 32) {
 | |
| 		return "", errcode.ErrJWTSecretKey
 | |
| 	}
 | |
| 	expireTime := time.Now().Add(vars.JwtExpireDay)
 | |
| 	claims := types.JwtClaims{
 | |
| 		ID:        id,
 | |
| 		Identity:  identity,
 | |
| 		Client:    client,
 | |
| 		Extend:    extend,
 | |
| 		Owner:     owner,
 | |
| 		Role:      role,
 | |
| 		ExpiresAt: expireTime.Unix(),
 | |
| 	}
 | |
| 
 | |
| 	byte, err := json.Marshal(claims)
 | |
| 	if err != nil {
 | |
| 		return "", errcode.ErrJWTJsonEncode
 | |
| 	}
 | |
| 
 | |
| 	token, err := AesEncryptCBC(byte)
 | |
| 	if err != nil {
 | |
| 		return "", err
 | |
| 	}
 | |
| 	return token, nil
 | |
| }
 | |
| 
 | |
| func AesEncryptCBC(plan []byte) (string, error) {
 | |
| 
 | |
| 	// 分组秘钥
 | |
| 	// NewCipher该函数限制了输入k的长度必须为16, 24或者32
 | |
| 	block, err := aes.NewCipher(JwtSecret)
 | |
| 	if err != nil {
 | |
| 		return "", errcode.ErrJWTSecretKey
 | |
| 	}
 | |
| 	// 获取秘钥块的长度
 | |
| 	blockSize := block.BlockSize()
 | |
| 	// 补全码
 | |
| 	plan = PKCS7Padding(plan, blockSize)
 | |
| 	// 加密模式
 | |
| 	blockMode := cipher.NewCBCEncrypter(block, JwtSecret[:blockSize])
 | |
| 	// 创建数组
 | |
| 	cryted := make([]byte, len(plan))
 | |
| 	// 加密
 | |
| 	blockMode.CryptBlocks(cryted, plan)
 | |
| 	return base64.StdEncoding.EncodeToString(cryted), nil
 | |
| }
 | |
| 
 | |
| func AesDecryptCBC(cryted string) (b []byte, err error) {
 | |
| 	if (JwtSecretLen == 16 || JwtSecretLen == 24 || JwtSecretLen == 32) == false {
 | |
| 		return nil, errcode.ErrJWTSecretKey
 | |
| 	}
 | |
| 	// 转成字节数组
 | |
| 	crytedByte, err := base64.StdEncoding.DecodeString(cryted)
 | |
| 	if err != nil {
 | |
| 		return nil, errcode.ErrJWTBase64Decode
 | |
| 	}
 | |
| 	// 分组秘钥
 | |
| 	block, err := aes.NewCipher(JwtSecret)
 | |
| 	if err != nil {
 | |
| 		return nil, errcode.ErrJWTSecretKey
 | |
| 	}
 | |
| 	// 获取秘钥块的长度
 | |
| 	blockSize := block.BlockSize()
 | |
| 	// 加密模式
 | |
| 	blockMode := cipher.NewCBCDecrypter(block, JwtSecret[:blockSize])
 | |
| 	// 创建数组
 | |
| 	orig := make([]byte, len(crytedByte))
 | |
| 	// 解密
 | |
| 	blockMode.CryptBlocks(orig, crytedByte)
 | |
| 	// 去补全码
 | |
| 	orig = PKCS7UnPadding(orig, blockSize)
 | |
| 	if orig == nil {
 | |
| 		return nil, errcode.ErrJWTAuthParseFail
 | |
| 	}
 | |
| 	return orig, nil
 | |
| }
 | |
| 
 | |
| func PKCS7Padding(ciphertext []byte, blocksize int) []byte {
 | |
| 	padding := blocksize - len(ciphertext)%blocksize
 | |
| 	padtext := bytes.Repeat([]byte{byte(padding)}, padding)
 | |
| 	return append(ciphertext, padtext...)
 | |
| }
 | |
| 
 | |
| // 去码
 | |
| // bug:runtime error: slice bounds out of range [:-22]
 | |
| func PKCS7UnPadding(origData []byte, blocksize int) []byte {
 | |
| 	if blocksize <= 0 {
 | |
| 		return nil
 | |
| 	}
 | |
| 	if origData == nil || len(origData) == 0 {
 | |
| 		return nil
 | |
| 	}
 | |
| 	if len(origData)%blocksize != 0 {
 | |
| 		return nil
 | |
| 	}
 | |
| 
 | |
| 	length := len(origData)
 | |
| 	unpadding := int(origData[length-1])
 | |
| 
 | |
| 	if length-unpadding <= 0 {
 | |
| 		return nil
 | |
| 	}
 | |
| 	return origData[:(length - unpadding)]
 | |
| }
 | |
| 
 | |
| func ParseTokenAes(token string) (*types.JwtClaims, error) {
 | |
| 	token = strings.TrimSpace(token)
 | |
| 	data, err := AesDecryptCBC(token)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	var ac *types.JwtClaims
 | |
| 	err = json.Unmarshal(data, &ac)
 | |
| 	if err != nil {
 | |
| 		return nil, errcode.ErrJWTAuthParseFail
 | |
| 	}
 | |
| 
 | |
| 	expireTime := time.Now().Unix()
 | |
| 	if expireTime > ac.ExpiresAt {
 | |
| 		return nil, errcode.ErrJWTAuthExpire
 | |
| 	}
 | |
| 
 | |
| 	return ac, nil
 | |
| }
 |