Commit 5d033468 authored by shajiaiming's avatar shajiaiming

接口加密

parent 0a4c7d5d
package config
var (
ApiAuthConfig = map[string]map[string]string{
"DEMO": {
"md5": "IgkibX71IEf382PT",
"aes": "IgkibX71IEf382PT",
"rsa": "rsa/public.pem",
},
}
)
const (
AppMode = "release" //debug or release
AppPort = ":9999"
AppName = "go-gin-api"
// 签名超时时间
AppSignExpiry = "120"
// RSA Private File
AppRsaPrivateFile = "rsa/private.pem"
// 超时时间
AppReadTimeout = 120
AppWriteTimeout = 120
// 日志文件
AppAccessLogName = "log/" + AppName + "-access.log"
AppErrorLogName = "log/" + AppName + "-error.log"
AppGrpcLogName = "log/" + AppName + "-grpc.log"
// 系统告警邮箱信息
SystemEmailUser = "xinliangnote@163.com"
SystemEmailPass = "" //密码或授权码
SystemEmailHost = "smtp.163.com"
SystemEmailPort = 465
// 告警接收人
ErrorNotifyUser = "xinliangnote@163.com"
// 告警开关 1=开通 -1=关闭
ErrorNotifyOpen = -1
// Jaeger 配置信息
JaegerHostPort = "127.0.0.1:6831"
// Jaeger 配置开关 1=开通 -1=关闭
JaegerOpen = 1
)
......@@ -27,6 +27,7 @@ require (
github.com/pilu/fresh v0.0.0-20190826141211-0fa698148017 // indirect
github.com/satori/go.uuid v1.2.0 // indirect
github.com/valyala/fasttemplate v1.1.0 // indirect
github.com/xinliangnote/go-util v0.0.0-20200323134426-527984dc34bf
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 // indirect
gopkg.in/go-playground/validator.v9 v9.29.1
gopkg.in/ini.v1 v1.51.1 // indirect
......
......@@ -199,6 +199,8 @@ github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPU
github.com/valyala/fasttemplate v1.1.0 h1:RZqt0yGBsps8NGvLSGW804QQqCUYYLsaOjTVHy1Ocw4=
github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc=
github.com/xinliangnote/go-util v0.0.0-20200323134426-527984dc34bf h1:KgY8vAMPQDehrkivQgLBqlwBmDg7eK+ey76A8tCsQ3I=
github.com/xinliangnote/go-util v0.0.0-20200323134426-527984dc34bf/go.mod h1:3ZornrplU9tYj9ar9jchik1XPQ10ZbSXkbgxXR5PVaU=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
......
package aes
import (
config "bwallet/conf"
"bwallet/pkg/errno"
"bwallet/pkg/handler"
"bwallet/pkg/util"
"fmt"
"github.com/gin-gonic/gin"
"net/url"
"sort"
"strconv"
"strings"
"time"
)
var AppSecret string
// MD5 组合加密
func Aes() gin.HandlerFunc {
return func(c *gin.Context) {
sign, err := verifySign(c)
if sign != nil {
handler.SendResponse(c, nil, sign)
c.Abort()
return
}
if err != nil {
handler.SendResponse(c, err, nil)
c.Abort()
return
}
c.Next()
}
}
// 验证签名
func verifySign(c *gin.Context) (map[string]string, error) {
_ = c.Request.ParseForm()
req := c.Request.Form
debug := strings.Join(c.Request.Form["debug"], "")
ak := strings.Join(c.Request.Form["ak"], "")
sn := strings.Join(c.Request.Form["sn"], "")
ts := strings.Join(c.Request.Form["ts"], "")
// 验证来源
value, ok := config.ApiAuthConfig[ak]
if ok {
AppSecret = value["md5"]
} else {
return nil, errno.ErrAk
}
if debug == "1" {
currentUnix := util.GetCurrentUnix()
req.Set("ts", strconv.FormatInt(currentUnix, 10))
res := map[string]string{
"ts": strconv.FormatInt(currentUnix, 10),
"sn": createSign(req),
}
return res, nil
}
// 验证过期时间
timestamp := time.Now().Unix()
exp, _ := strconv.ParseInt(config.AppSignExpiry, 10, 64)
tsInt, _ := strconv.ParseInt(ts, 10, 64)
if tsInt > timestamp || timestamp-tsInt >= exp {
return nil, errno.ErrTs
}
// 验证签名
if sn == "" || sn != createSign(req) {
return nil, errno.ErrSn
}
return nil, nil
}
// 创建签名
func createSign(params url.Values) string {
// 自定义 MD5 组合
return util.EncodeMD5(AppSecret + createEncryptStr(params) + AppSecret)
}
func createEncryptStr(params url.Values) string {
var key []string
var str = ""
for k := range params {
if k != "sn" && k != "debug" {
key = append(key, k)
}
}
sort.Strings(key)
for i := 0; i < len(key); i++ {
if i == 0 {
str = fmt.Sprintf("%v=%v", key[i], params.Get(key[i]))
} else {
str = str + fmt.Sprintf("&%v=%v", key[i], params.Get(key[i]))
}
}
return str
}
package md5
import (
config "bwallet/conf"
"bwallet/pkg/errno"
"bwallet/pkg/handler"
"bwallet/pkg/util"
"fmt"
"github.com/gin-gonic/gin"
"net/url"
"sort"
"strconv"
"strings"
"time"
)
var AppSecret string
// MD5 组合加密
func Md5() gin.HandlerFunc {
return func(c *gin.Context) {
sign, err := verifySign(c)
if sign != nil {
handler.SendResponse(c, nil, sign)
c.Abort()
return
}
if err != nil {
handler.SendResponse(c, err, nil)
c.Abort()
return
}
c.Next()
}
}
// 验证签名
func verifySign(c *gin.Context) (map[string]string, error) {
_ = c.Request.ParseForm()
req := c.Request.Form
debug := strings.Join(c.Request.Form["debug"], "")
ak := strings.Join(c.Request.Form["ak"], "")
sn := strings.Join(c.Request.Form["sn"], "")
ts := strings.Join(c.Request.Form["ts"], "")
// 验证来源
value, ok := config.ApiAuthConfig[ak]
if ok {
AppSecret = value["md5"]
} else {
return nil, errno.ErrAk
}
if debug == "1" {
currentUnix := util.GetCurrentUnix()
req.Set("ts", strconv.FormatInt(currentUnix, 10))
res := map[string]string{
"ts": strconv.FormatInt(currentUnix, 10),
"sn": createSign(req),
}
return res, nil
}
// 验证过期时间
timestamp := time.Now().Unix()
exp, _ := strconv.ParseInt(config.AppSignExpiry, 10, 64)
tsInt, _ := strconv.ParseInt(ts, 10, 64)
if tsInt > timestamp || timestamp-tsInt >= exp {
return nil, errno.ErrTs
}
// 验证签名
if sn == "" || sn != createSign(req) {
return nil, errno.ErrSn
}
return nil, nil
}
// 创建签名
func createSign(params url.Values) string {
// 自定义 MD5 组合
return util.EncodeMD5(AppSecret + createEncryptStr(params) + AppSecret)
}
func createEncryptStr(params url.Values) string {
var key []string
var str = ""
for k := range params {
if k != "sn" && k != "debug" {
key = append(key, k)
}
}
sort.Strings(key)
for i := 0; i < len(key); i++ {
if i == 0 {
str = fmt.Sprintf("%v=%v", key[i], params.Get(key[i]))
} else {
str = str + fmt.Sprintf("&%v=%v", key[i], params.Get(key[i]))
}
}
return str
}
package rsa
import (
config "bwallet/conf"
"bwallet/pkg/errno"
"bwallet/pkg/handler"
"bwallet/pkg/util"
"errors"
"fmt"
"github.com/gin-gonic/gin"
"github.com/xinliangnote/go-util/rsa"
"net/url"
"sort"
"strconv"
"strings"
"time"
)
var AppSecret string
// RSA 非对称加密
func Rsa() gin.HandlerFunc {
return func(c *gin.Context) {
sign, err := verifySign(c)
if sign != nil {
handler.SendResponse(c, nil, sign)
c.Abort()
return
}
if err != nil {
handler.SendResponse(c, err, nil)
c.Abort()
return
}
c.Next()
}
}
// 验证签名
func verifySign(c *gin.Context) (map[string]string, error) {
_ = c.Request.ParseForm()
req := c.Request.Form
debug := strings.Join(c.Request.Form["debug"], "")
ak := strings.Join(c.Request.Form["ak"], "")
sn := strings.Join(c.Request.Form["sn"], "")
ts := strings.Join(c.Request.Form["ts"], "")
// 验证来源
value, ok := config.ApiAuthConfig[ak]
if ok {
AppSecret = value["rsa"]
} else {
return nil, errno.ErrAk
}
if debug == "1" {
currentUnix := util.GetCurrentUnix()
req.Set("ts", strconv.FormatInt(currentUnix, 10))
sn, err := createSign(req)
if err != nil {
return nil, errno.ErrSn
}
res := map[string]string{
"ts": strconv.FormatInt(currentUnix, 10),
"sn": sn,
}
return res, nil
}
// 验证过期时间
timestamp := time.Now().Unix()
exp, _ := strconv.ParseInt(config.AppSignExpiry, 10, 64)
tsInt, _ := strconv.ParseInt(ts, 10, 64)
if tsInt > timestamp || timestamp-tsInt >= exp {
return nil, errno.ErrTs
}
// 验证签名
if sn == "" {
return nil, errno.ErrSn
}
decryptStr, decryptErr := rsa.PrivateDecrypt(sn, config.AppRsaPrivateFile)
if decryptErr != nil {
return nil, errors.New(decryptErr.Error())
}
if decryptStr != createEncryptStr(req) {
return nil, errno.ErrSn
}
return nil, nil
}
// 创建签名
func createSign(params url.Values) (string, error) {
return rsa.PublicEncrypt(createEncryptStr(params), AppSecret)
}
func createEncryptStr(params url.Values) string {
var key []string
var str = ""
for k := range params {
if k != "sn" && k != "debug" {
key = append(key, k)
}
}
sort.Strings(key)
for i := 0; i < len(key); i++ {
if i == 0 {
str = fmt.Sprintf("%v=%v", key[i], params.Get(key[i]))
} else {
str = str + fmt.Sprintf("&%v=%v", key[i], params.Get(key[i]))
}
}
return str
}
package models
import (
"bwallet/pkg/setting"
"github.com/jinzhu/gorm"
"time"
)
type Streamer struct {
Uid int32 `gorm:"type:int(11);primary key"`
UserName string `gorm:"type:varchar(64);unique;not null"`
NickName string `gorm:"type:varchar(128)"`
Password string `gorm:"type:varchar(32);not null"`
RegTime int64 `gorm:"type:datetime"`
LastLoginTime int64 `gorm:"type:datetime"`
RegIp uint32 `gorm:"type:int(10)"`
LastLoginIp uint32 `gorm:"type:int(10)"`
Status uint8 `gorm:"not null;default:0"`
PlatformId int64 `gorm:"not null;default:0"`
}
func (w Streamer) TableName() string {
return setting.DatabaseSetting.Name_Sources + ".wallet_streamer"
}
func GetStreamer(id int32) (*Streamer, error) {
var live Streamer
err := db.Where("id = ?", id).First(&live).Error
if err != nil && err != gorm.ErrRecordNotFound {
return nil, err
}
err = db.Model(&live).Error
if err != nil && err != gorm.ErrRecordNotFound {
return nil, err
}
return &live, nil
}
func ExistStreamerById(id int32) (bool, error) {
var live Streamer
err := db.Select("uid").Where("uid = ?", id).First(&live).Error
if err != nil && err != gorm.ErrRecordNotFound {
return false, err
}
if live.Uid > 0 {
return true, nil
}
return false, nil
}
func GetStreamerTotal(maps interface{}) (int, error) {
var count int
if err := db.Model(&Streamer{}).Where(maps).Count(&count).Error; err != nil {
return 0, err
}
return count, nil
}
func GetStreamers(pageNum, pageSize int, maps interface{}) ([]*Streamer, error) {
var live []*Streamer
err := db.Where(maps).Preload("Category").Order("sort desc").Order("create_time desc").Offset(pageNum).Limit(pageSize).Find(&live).Error
if err != nil && err != gorm.ErrRecordNotFound {
return nil, err
}
return live, nil
}
func AddStreamer(data map[string]interface{}) (error) {
streamer := Streamer{
UserName: data["username"].(string),
NickName: data["nickname"].(string),
Password: data["password"].(string),
RegTime: time.Now().Unix(),
LastLoginTime: time.Now().Unix(),
RegIp: data["reg_ip"].(uint32),
LastLoginIp: data["last_login_ip"].(uint32),
Status: data["status"].(uint8),
PlatformId: data["platform_id"].(int64),
}
if err := db.Create(&streamer).Error; err != nil {
return err
}
return nil
}
func EditStreamer(id int32, data interface{}) error {
if err := db.Model(&Streamer{}).Where("uid = ?", id).Updates(data).Error; err != nil {
return err
}
return nil
}
func DeleteStreamer(id int32) error {
if err := db.Where("id = ?", id).Delete(Streamer{}).Error; err != nil {
return err
}
return nil
}
package encrypt
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"encoding/base64"
)
// 加密 aes_128_cbc
func AesEncrypt(encryptStr string, key []byte, iv string) (string, error) {
encryptBytes := []byte(encryptStr)
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}
blockSize := block.BlockSize()
encryptBytes = pkcs5Padding(encryptBytes, blockSize)
blockMode := cipher.NewCBCEncrypter(block, []byte(iv))
encrypted := make([]byte, len(encryptBytes))
blockMode.CryptBlocks(encrypted, encryptBytes)
return base64.URLEncoding.EncodeToString(encrypted), nil
}
// 解密
func AesDecrypt(decryptStr string, key []byte, iv string) (string, error) {
decryptBytes, err := base64.URLEncoding.DecodeString(decryptStr)
if err != nil {
return "", err
}
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}
blockMode := cipher.NewCBCDecrypter(block, []byte(iv))
decrypted := make([]byte, len(decryptBytes))
blockMode.CryptBlocks(decrypted, decryptBytes)
decrypted = pkcs5UnPadding(decrypted)
return string(decrypted), nil
}
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(decrypted []byte) []byte {
length := len(decrypted)
unPadding := int(decrypted[length-1])
return decrypted[:(length - unPadding)]
}
......@@ -65,6 +65,9 @@ var (
ErrValidation = &Errno{Code: 20001, Message: "Validation failed."}
ErrDatabase = &Errno{Code: 20002, Message: "Database error."}
ErrTs = &Errno{Code: 20003, Message: "Ts error."}
ErrSn = &Errno{Code: 20004, Message: "Sn error."}
ErrAk = &Errno{Code: 20005, Message: "Ak error."}
// coin errors
ErrCoinNotFound = &Errno{Code: 20101, Message: "The coin was not found."}
......
package util
import "time"
func GetCurrentDate() string {
return time.Now().Format("2006/01/02 15:04:05")
}
func GetCurrentUnix() int64 {
return time.Now().Unix()
}
func GetCurrentMilliUnix() int64 {
return time.Now().UnixNano() / 1000000
}
func GetCurrentNanoUnix() int64 {
return time.Now().UnixNano()
}
......@@ -75,7 +75,10 @@ func AddLiveInfo(c *gin.Context) {
Sort: info.Sort,
}
infoService.Add()
if err := infoService.Add(); err != nil {
handler.SendResponse(c, errno.ErrAddLiveBanner, nil)
return
}
handler.SendResponse(c, nil, nil)
}
......
......@@ -3,6 +3,7 @@ package routers
import (
"bwallet/middleware/jwt"
"bwallet/middleware/log"
"bwallet/middleware/sign/aes"
"bwallet/pkg/e"
"github.com/gin-gonic/gin"
......@@ -27,6 +28,7 @@ func InitRouter() *gin.Engine {
//r.POST("/upload", api.UploadImage)
client := r.Group("/interface")
client.Use(aes.Aes())
client.GET("/news", app.GetNews)
client.GET("/one-news", app.GetOneNews)
client.GET("/articles", app.GetArticle)
......
package streamer_service
import (
"bwallet/models"
)
type Streamer struct {
Uid int32
UserName string
NickName string
Password string
RegTime int64
LastLoginTime int64
RegIp uint32
LastLoginIp uint32
Status uint8
PlatformId int64
PageNum int
PageSize int
}
func (s *Streamer) GetOneStreamer() (*models.Streamer, error) {
streamer, err := models.GetStreamer(s.Uid)
if err != nil {
return nil, err
}
return streamer, nil
}
func (s *Streamer) GetAll() ([]*models.Streamer, error) {
var streamer []*models.Streamer
streamer, err := models.GetStreamers(s.PageNum, s.PageSize, s.getMaps())
if err != nil {
return nil, err
}
return streamer, nil
}
func (s *Streamer) Add() error {
streamer := map[string]interface{}{
"username": s.UserName,
"nickname": s.NickName,
"password": s.Password,
"reg_ip": s.RegIp,
"last_login_ip": s.LastLoginIp,
"status": s.Status,
"platform_id": s.PlatformId,
}
if err := models.AddStreamer(streamer); err != nil {
return err
}
return nil
}
func (s *Streamer) Edit() error {
return models.EditStreamer(s.Uid, map[string]interface{}{
"username": s.UserName,
"nickname": s.NickName,
"password": s.Password,
"reg_ip": s.RegIp,
"last_login_ip": s.LastLoginIp,
"status": s.Status,
"platform_id": s.PlatformId,
})
}
func (s *Streamer) ExistById() (bool, error) {
return models.ExistStreamerById(s.Uid)
}
func (s *Streamer) Count() (int, error) {
return models.GetStreamerTotal(s.getMaps())
}
func (s *Streamer) Delete() error {
return models.DeleteStreamer(s.Uid)
}
func (s *Streamer) getMaps() (map[string]interface{}) {
maps := make(map[string]interface{})
if s.Uid != 0 {
maps["id"] = s.Uid
}
if s.PlatformId != 0 {
maps["platform_id"] = s.PlatformId
}
maps["status"] = s.Status
return maps
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment