From 2903be6223a9b18ddabab526c95014ef10ae5ad9 Mon Sep 17 00:00:00 2001 From: denghui <1016848185@qq.com> Date: Mon, 16 Jun 2025 10:19:38 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=20rsa=20=E5=AF=86=E9=92=A5?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/reward/reward.go | 1 + api/reward/v1/reward.go | 23 ++++ .../reward/reward_v1_reward_callback.go | 29 ++++ .../storeAdmin/storeAdmin_v1_info.go | 2 + internal/dao/internal/rewards.go | 2 + internal/dao/internal/users.go | 2 - internal/logic/logic.go | 1 - internal/logic/user/user.go | 1 - internal/model/do/rewards.go | 1 + internal/model/do/users.go | 1 - internal/model/entity/rewards.go | 1 + internal/model/entity/users.go | 1 - manifest/config/config.yaml | 8 +- manifest/config/private.pem | 28 ---- manifest/config/public.pem | 9 -- manifest/config/全游-正式环境密钥.txt | 38 ++++++ manifest/config/全游-测试环境密钥.txt | 38 ++++++ utility/gamelife/gamelife.go | 19 +-- utility/rsa/rsa.go | 126 ++++++++++++------ 19 files changed, 235 insertions(+), 96 deletions(-) create mode 100644 internal/controller/reward/reward_v1_reward_callback.go delete mode 100644 manifest/config/private.pem delete mode 100644 manifest/config/public.pem create mode 100644 manifest/config/全游-正式环境密钥.txt create mode 100644 manifest/config/全游-测试环境密钥.txt diff --git a/api/reward/reward.go b/api/reward/reward.go index c77e311..1850786 100644 --- a/api/reward/reward.go +++ b/api/reward/reward.go @@ -19,4 +19,5 @@ type IRewardV1 interface { UpdateStoreReward(ctx context.Context, req *v1.UpdateStoreRewardReq) (res *v1.UpdateStoreRewardRes, err error) DeleteSystemReward(ctx context.Context, req *v1.DeleteSystemRewardReq) (res *v1.DeleteSystemRewardRes, err error) DeleteStoreReward(ctx context.Context, req *v1.DeleteStoreRewardReq) (res *v1.DeleteStoreRewardRes, err error) + RewardCallback(ctx context.Context, req *v1.RewardCallbackReq) (res *v1.RewardCallbackRes, err error) } diff --git a/api/reward/v1/reward.go b/api/reward/v1/reward.go index 86d95cf..a912b2e 100644 --- a/api/reward/v1/reward.go +++ b/api/reward/v1/reward.go @@ -131,3 +131,26 @@ type DeleteStoreRewardReq struct { type DeleteStoreRewardRes struct { Success bool `json:"success" dc:"删除成功"` } + +type RewardCallbackReq struct { + g.Meta `path:"/reward/callback" method:"post" tags:"Reward" summary:"(系统)奖励回调"` + UId string `json:"uid"` + OrderId string `json:"order_id"` + PrizeChannelId string `json:"prize_channel_id"` + PrizeId string `json:"prize_id" v:"required|#券ID不能为空"` + PrizeType uint32 `json:"prize_type"` + PrizeSubType uint32 `json:"prize_sub_type"` + Num uint32 `json:"num"` + CustomInfo string `json:"custom_info"` +} +type RewardCallbackRes struct { + ErrCode int32 `json:"errcode"` // 必填 + ErrMsg string `json:"errmsg"` + Appid string `json:"appid"` + OrderId string `json:"order_id"` // 必填 + Data []RewardCallbackData `json:"data"` // 必填 +} +type RewardCallbackData struct { + PrizeCode string `json:"prize_code"` // 必填 + Comment string `json:"comment"` +} diff --git a/internal/controller/reward/reward_v1_reward_callback.go b/internal/controller/reward/reward_v1_reward_callback.go new file mode 100644 index 0000000..53967c7 --- /dev/null +++ b/internal/controller/reward/reward_v1_reward_callback.go @@ -0,0 +1,29 @@ +package reward + +import ( + "context" + "fmt" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/glog" + + "github.com/gogf/gf/v2/errors/gcode" + "github.com/gogf/gf/v2/errors/gerror" + + "server/api/reward/v1" +) + +func (c *ControllerV1) RewardCallback(ctx context.Context, req *v1.RewardCallbackReq) (res *v1.RewardCallbackRes, err error) { + appId := g.RequestFromCtx(ctx).GetHeader("Custom-Data-Appid") + timestamp := g.RequestFromCtx(ctx).GetHeader("Custom-Data-Timestamp") + nonce := g.RequestFromCtx(ctx).GetHeader("Custom-Data-Nonce") + auth := g.RequestFromCtx(ctx).GetHeader("Custom-Data-Auth") + + glog.Infof(ctx, "appId: %s, timestamp: %s, nonce: %s, auth: %s", appId, timestamp, nonce, auth) + secret := "" + data := fmt.Sprintf("%s%s%s%s%d%d%d%s%s%s#%s", req.UId, req.OrderId, req.PrizeId, req.PrizeChannelId, req.PrizeType, req.PrizeSubType, req.Num, appId, timestamp, nonce, secret) + if data != auth { + + } + + return nil, gerror.NewCode(gcode.CodeNotImplemented) +} diff --git a/internal/controller/storeAdmin/storeAdmin_v1_info.go b/internal/controller/storeAdmin/storeAdmin_v1_info.go index e785aff..20e2d7b 100644 --- a/internal/controller/storeAdmin/storeAdmin_v1_info.go +++ b/internal/controller/storeAdmin/storeAdmin_v1_info.go @@ -2,6 +2,7 @@ package storeAdmin import ( "context" + "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/errors/gcode" "github.com/gogf/gf/v2/errors/gerror" @@ -10,5 +11,6 @@ import ( ) func (c *ControllerV1) Info(ctx context.Context, req *v1.InfoReq) (res *v1.InfoRes, err error) { + g.RequestFromCtx(ctx) return nil, gerror.NewCode(gcode.CodeNotImplemented) } diff --git a/internal/dao/internal/rewards.go b/internal/dao/internal/rewards.go index d60fc10..93949fb 100644 --- a/internal/dao/internal/rewards.go +++ b/internal/dao/internal/rewards.go @@ -34,6 +34,7 @@ type RewardsColumns struct { CreatedAt string // 创建时间 UpdatedAt string // 更新时间 DeletedAt string // 软删除时间戳 + RemainStock string // 剩余库存数量 } // rewardsColumns holds the columns for the table rewards. @@ -51,6 +52,7 @@ var rewardsColumns = RewardsColumns{ CreatedAt: "created_at", UpdatedAt: "updated_at", DeletedAt: "deleted_at", + RemainStock: "remain_stock", } // NewRewardsDao creates and returns a new DAO object for table data access. diff --git a/internal/dao/internal/users.go b/internal/dao/internal/users.go index 3ebfb26..340eaf7 100644 --- a/internal/dao/internal/users.go +++ b/internal/dao/internal/users.go @@ -27,7 +27,6 @@ type UsersColumns struct { Nickname string // 昵称 Avatar string // 用户头像URL PasswordHash string // 密码哈希 - Email string // 邮箱地址 PhoneNumber string // 手机号 WxPopenId string // 微信 PopenID QqPopenId string // QQ PopenID @@ -48,7 +47,6 @@ var usersColumns = UsersColumns{ Nickname: "nickname", Avatar: "avatar", PasswordHash: "password_hash", - Email: "email", PhoneNumber: "phone_number", WxPopenId: "wx_popen_id", QqPopenId: "qq_popen_id", diff --git a/internal/logic/logic.go b/internal/logic/logic.go index c0dd416..eeea66b 100644 --- a/internal/logic/logic.go +++ b/internal/logic/logic.go @@ -13,7 +13,6 @@ import ( _ "server/internal/logic/reward" _ "server/internal/logic/rewardType" _ "server/internal/logic/role" - _ "server/internal/logic/sms" _ "server/internal/logic/store" _ "server/internal/logic/storeAdmin" _ "server/internal/logic/storeRole" diff --git a/internal/logic/user/user.go b/internal/logic/user/user.go index fcdc640..aae6a8d 100644 --- a/internal/logic/user/user.go +++ b/internal/logic/user/user.go @@ -156,7 +156,6 @@ func (s *sUser) Info(ctx context.Context, in *model.UserInfoIn) (out *model.User Username: user.Username, Nickname: user.Nickname, Avatar: user.Avatar, - Email: user.Email, PhoneNumber: user.PhoneNumber, WxPopenId: user.WxPopenId, QQPopenId: user.QqPopenId, diff --git a/internal/model/do/rewards.go b/internal/model/do/rewards.go index 623bbb6..768e5c7 100644 --- a/internal/model/do/rewards.go +++ b/internal/model/do/rewards.go @@ -25,4 +25,5 @@ type Rewards struct { CreatedAt *gtime.Time // 创建时间 UpdatedAt *gtime.Time // 更新时间 DeletedAt *gtime.Time // 软删除时间戳 + RemainStock interface{} // 剩余库存数量 } diff --git a/internal/model/do/users.go b/internal/model/do/users.go index 1d5493f..3920057 100644 --- a/internal/model/do/users.go +++ b/internal/model/do/users.go @@ -18,7 +18,6 @@ type Users struct { Nickname interface{} // 昵称 Avatar interface{} // 用户头像URL PasswordHash interface{} // 密码哈希 - Email interface{} // 邮箱地址 PhoneNumber interface{} // 手机号 WxPopenId interface{} // 微信 PopenID QqPopenId interface{} // QQ PopenID diff --git a/internal/model/entity/rewards.go b/internal/model/entity/rewards.go index 15af696..b4933e2 100644 --- a/internal/model/entity/rewards.go +++ b/internal/model/entity/rewards.go @@ -23,4 +23,5 @@ type Rewards struct { CreatedAt *gtime.Time `json:"createdAt" orm:"created_at" description:"创建时间"` // 创建时间 UpdatedAt *gtime.Time `json:"updatedAt" orm:"updated_at" description:"更新时间"` // 更新时间 DeletedAt *gtime.Time `json:"deletedAt" orm:"deleted_at" description:"软删除时间戳"` // 软删除时间戳 + RemainStock int `json:"remainStock" orm:"remain_stock" description:"剩余库存数量"` // 剩余库存数量 } diff --git a/internal/model/entity/users.go b/internal/model/entity/users.go index 9fa9514..4f4153e 100644 --- a/internal/model/entity/users.go +++ b/internal/model/entity/users.go @@ -16,7 +16,6 @@ type Users struct { Nickname string `json:"nickname" orm:"nickname" description:"昵称"` // 昵称 Avatar string `json:"avatar" orm:"avatar" description:"用户头像URL"` // 用户头像URL PasswordHash string `json:"passwordHash" orm:"password_hash" description:"密码哈希"` // 密码哈希 - Email string `json:"email" orm:"email" description:"邮箱地址"` // 邮箱地址 PhoneNumber string `json:"phoneNumber" orm:"phone_number" description:"手机号"` // 手机号 WxPopenId string `json:"wxPopenId" orm:"wx_popen_id" description:"微信 PopenID"` // 微信 PopenID QqPopenId string `json:"qqPopenId" orm:"qq_popen_id" description:"QQ PopenID"` // QQ PopenID diff --git a/manifest/config/config.yaml b/manifest/config/config.yaml index e840458..6e0e827 100644 --- a/manifest/config/config.yaml +++ b/manifest/config/config.yaml @@ -34,10 +34,6 @@ wechat: ticketExpire: 60 token: "arenax" -rsa: - publickey: "./manifest/config/public.pem" - privatekey: "./manifest/config/private.pem" - #OSS配置 oss: aliyun: @@ -47,5 +43,7 @@ oss: endpoint: "oss-us-east-1.aliyuncs.com" gamelife: - platId: "b1749611654" + platId: "quanyou" + secret: "LqPQ2gbF" mode: "test" + rsaKey: "./manifest/config/全游-测试环境密钥.txt" diff --git a/manifest/config/private.pem b/manifest/config/private.pem deleted file mode 100644 index 1d99bcc..0000000 --- a/manifest/config/private.pem +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCHXJazSOFka3q+ -xyBqVuLtK+OElsgRQyQCRakBvcBkq5lIl1G+6ivuju+q3bemiYzOWah/H/+7848c -yu505CpJtRUvPiSaXqhwIAWAHvD1ckLo9xw3eh9uYdmnZx92+d+oKVcjZWz/M6qQ -g6GYf8kE0x8zDKw1Xd89y6xzo7DqFNnE9BHSxeFNSAgp+MOBPn7X2mdDOWl6eGLs -qXK6BTTFyeS0JaH1t0ra6JyQ5wau3WKpB22G3pK9+u8MQPKjM+JXdIZFA0eT2SeI -qbB0xRfU4fOmhn/eXVyNYws1s92hPq1Lu8/QHf6m6QNbmualgaSiEo/ogKGN1urj -/ARsTdbpAgMBAAECggEAF2DnakmhHA3wIjkUISmmgd39qq28GjclZfsQCIv0Sa7V -h5MS/E1HjylCvZkTmgDRv+X+Uw58xcJ4KjnmW2v43cgXw5QREFRe9RaivJEbftjg -M4pSZkaCXTcrN115MrxPY6TYNvXSkHUk9Va2tzcCygGItvFuYL04zFx8CXDxIkx7 -4NP3F3AGbQ4GACoIUsKNuQ0WIZO6WrxJP0sGH1iz+oxDIlEkEZAYHAKIIna3gaY5 -YBvOmRScGDO2K05fLxDJUK0x4nxkBRQ1NRu9Ud1Fo4zwUFxiwM4ZUjaLclgIgv8v -5h0urZY/j4994YtC4UvheC53UEAqDKjMWXnjH5u4nQKBgQDlwqSk6St7pAW1lpA+ -0OMKQgdDe+W+O2a0LPjaSevCX3Q9ml/ToRH+tmVUGOr2S301GqSRaPdauXBDvE29 -HSoD6gCEsT+TocSxyhn0Gg25fMDz3+H7XVOAj+tPg/IWJG8+KxO5gEwucb6Axl3w -NQ29l77SKFgMYitq8N1jjt6LMwKBgQCW0hJzx2dgaYmKrxctWOxfibTaCGBEn4+F -6YwmfGJg+qZ+FU+aBkwaocutIudHogIAOXp6e4J086a6cUwx/Eex1tvTztVa8A/W -8cRmk+DWIIYN4c/wePe3wDluddtRIgh54ukpFsgVsOEEmzp3GAa8fyUA7dVvuJlQ -z1torG11cwKBgQCImppzZiKxR0sRtOwcPOvQLIPPDroAyaZ9l4N5nZurnD8rZT52 -P/zH+T/zqUEBoM5XpXiU79ipOznRPALoXo+ddiJKwmuvZe3hWuzlYhwo3VCHbuQY -JFvCQ08/no5vtcfiKZB3qR0iPARs4gP2DkUWJUOSBeSbsD5qPb0TNV2BWwKBgAz+ -QBS1YxSNQwotl2OSu5pndKsr+Y8v599zhV1zbc5JCbrm/xqX3EqXEcLytNYZAO8g -BIs0xMJqkzyQsi3EPDD3/6w5r2vMLrEn1vG3X7FSz/m2MIHZCg5MgyYfBSvyMKS/ -hbLCga5MtLX+4YSND1eB5KA13SNo1dx+YLOd1zg9AoGAczXhM+n0beuXDhLkiAm3 -7Av8lJazrpZg2Oh79IrFJANjVyZZeOVaSfNXPumoDXMZvEMjkIaZZ50IzQfpVdLF -7J0Y/hFCTsX6b3JdkiluniiEh1a2I3tC3+Qa4sSPqKNdHcBJSmmcBcpzRLL5n2zc -bjt4KNf3ZQ3nHvPHnwrd7pg= ------END RSA PRIVATE KEY----- diff --git a/manifest/config/public.pem b/manifest/config/public.pem deleted file mode 100644 index f230ee3..0000000 --- a/manifest/config/public.pem +++ /dev/null @@ -1,9 +0,0 @@ ------BEGIN PUBLIC KEY----- -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAh1yWs0jhZGt6vscgalbi -7SvjhJbIEUMkAkWpAb3AZKuZSJdRvuor7o7vqt23pomMzlmofx//u/OPHMrudOQq -SbUVLz4kml6ocCAFgB7w9XJC6PccN3ofbmHZp2cfdvnfqClXI2Vs/zOqkIOhmH/J -BNMfMwysNV3fPcusc6Ow6hTZxPQR0sXhTUgIKfjDgT5+19pnQzlpenhi7KlyugU0 -xcnktCWh9bdK2uickOcGrt1iqQdtht6SvfrvDEDyozPiV3SGRQNHk9kniKmwdMUX -1OHzpoZ/3l1cjWMLNbPdoT6tS7vP0B3+pukDW5rmpYGkohKP6IChjdbq4/wEbE3W -6QIDAQAB ------END PUBLIC KEY----- diff --git a/manifest/config/全游-正式环境密钥.txt b/manifest/config/全游-正式环境密钥.txt new file mode 100644 index 0000000..8a84cdb --- /dev/null +++ b/manifest/config/全游-正式环境密钥.txt @@ -0,0 +1,38 @@ +正式环境 +-----BEGIN rsa public key----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzdNXFM1ny9+gV+zBwmXc +f21XKilaFdAfHB8959URJkp27JS2iqBuDVSaXQTGJcI6aHk0Cz1zCt2crZX9Z40X +zEhPE8MRLJZfKDgKbg1Gb7c7Dxj7B6+uTbIsGXV+13SE595VL6depxHfgQS425UM +isIPP0isdn7wKey3hJ/COPezOp6/bYwROEy+ZHOMoINWG5Lk3bX0e9axLH1/U19G +5ZqtnVlIqV90y9SiDPnuKu12EZRJ4Z5QrG0/CgAloO/97YLahOmoKDnk7dUIvN/w +A3B80AGP3aXU7cdwrQfXcDXPG2LoyM9MkSrgsBAOQdJsaDHksudEMqEWnDie/TRq +ewIDAQAB +-----END rsa public key----- + +-----BEGIN rsa private key----- +MIIEpQIBAAKCAQEAzdNXFM1ny9+gV+zBwmXcf21XKilaFdAfHB8959URJkp27JS2 +iqBuDVSaXQTGJcI6aHk0Cz1zCt2crZX9Z40XzEhPE8MRLJZfKDgKbg1Gb7c7Dxj7 +B6+uTbIsGXV+13SE595VL6depxHfgQS425UMisIPP0isdn7wKey3hJ/COPezOp6/ +bYwROEy+ZHOMoINWG5Lk3bX0e9axLH1/U19G5ZqtnVlIqV90y9SiDPnuKu12EZRJ +4Z5QrG0/CgAloO/97YLahOmoKDnk7dUIvN/wA3B80AGP3aXU7cdwrQfXcDXPG2Lo +yM9MkSrgsBAOQdJsaDHksudEMqEWnDie/TRqewIDAQABAoIBAQCRshNHV2stBrxi +4OX7LM2bqhN0ddcd77fF2Vuh2tIL79Qk/dQFZzDf4M5wH+v/WHCt+XXcqv/fZiX9 +PlolTdvVsC3ByGhEzqDHQHwpkN4WQHbe5gj0VOimeQP8dY53BzT5SQm19NzsmJtE +ocoVLXm2U04lttTWAF8S3ky95bS/S1qMbCLlB0ChqCWyZBnLkZgWLK4Vglog3H4H +cClMcPNm/kJNLleQ8QH+CYs8fAABaOuD9dEXJAC4XiKUhyDythWjux9pccjDXJ2u +xIg1t2x+jBrp5uV8MfjxJRAe2sgCj/qcpT9vTbP8yHTshwkVPYBbsd/RlWlo/zXr +8WyN89T5AoGBAN949GqfB/GCjRdf4Bhs57tOc5z9GCZTERcOL07ygma9SLAZ13qK +706IThTz1vgj3ZpOsIZ3UspZiVpXkmDZekWrKK7UhB+TMWLDRzlySXlxLIC++JUT +VG5ugYPNOG2J18qB0o1V/KqUVMr7MBlnxQKTAoHWnImWMZICAC9q2meNAoGBAOvI +0whYFM9zvs5ghIgH3K2z56COPf+V6kb/FlhZhaYFu73YtMu2GxAfwin6ZfTHNypx +KWM5y0en4lC962VbfQYphtL0/PdEhNucRMOTGbLQnoKPDWL7JaDdG0MCkhKnSZlo +okCughG/UNBMHCLDObYLighbkKKMihmidoDH/jQnAoGBALqXYvWXvekwyaAHxLSA +Umk6Exy00zJEz5NBm8y+fpVMXOH1Yc8HLNOUyiWCiC7+u2y5YXmVLkKYyi/tyOIn +FIoRZNG9zmgS3fyJ8vGLdL/6+F6zlhnbXvcqO+gSNZh4rP6AsY6jimnfmoE1hS7h +T0Vb/I7u5BuZleBE3WS6QoyNAoGBAMkd4ovifdW6F833W/SgKCbuJqu3yMBiwpPO +b+PqcGp9x3cXCpgcfBcTz814rVDOQIruPWxK1s8HL67JYKlzEUCZWUxF9iSACIc+ +UxUzOx9gfWRF2xhLuvvsvZ056xkIImo9avCbKY0z0B3sXa91MJvMWe/pEoTkNcPJ +5STR8k3PAoGAE334SjfwxpzYG+lcf9Oyli2HbFHO8u6PXhPQ+xgYUh45KeDIWo0Q +j0fmiNrmSYs3Ojs1QtUZMNQWaRmR7Xcysa9pcIFatbbwMfafBO+nROaBbo+bhVKN +VRN1as06j/dVhfYWuwx8BxJjsskllpfcSi7riA6nLrnxbUNktpK6/gs= +-----END rsa private key----- \ No newline at end of file diff --git a/manifest/config/全游-测试环境密钥.txt b/manifest/config/全游-测试环境密钥.txt new file mode 100644 index 0000000..fa15827 --- /dev/null +++ b/manifest/config/全游-测试环境密钥.txt @@ -0,0 +1,38 @@ +测试环境 +-----BEGIN rsa public key----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAks8Rak/Gt6IuDcjcpKCI +NTj04pWozRaZ1Ryy5DpmtwYW9c7AayIqsIGGTcl8/QiaamTThB2pnn8dZ6o8iCXb +z9zG8Jq8GqX4nm8bT7/y3zaTgV6oScY7mw4hfZPSUv2lHaLij4whIrYCOi4mW+lh +9Ab//0NbJ5XHxRnlYscuOIKs64ss18disWWFwl5IgCVTPsqqlYZgkwYIdE2FpZds +rKYLDY1T16Qwvs+H0rlRZ5yKY8Xhj2x+oU8WygSbFPIZ+sONHyfJ4sxjGRdmxohD +4roNycwuHqjOZJauw3Mdkl0ibJE0oCL5yAf8D7li2aUP/0NRSfb64dfG6RhDH6HQ +QQIDAQAB +-----END rsa public key----- + +-----BEGIN rsa private key----- +MIIEogIBAAKCAQEAks8Rak/Gt6IuDcjcpKCINTj04pWozRaZ1Ryy5DpmtwYW9c7A +ayIqsIGGTcl8/QiaamTThB2pnn8dZ6o8iCXbz9zG8Jq8GqX4nm8bT7/y3zaTgV6o +ScY7mw4hfZPSUv2lHaLij4whIrYCOi4mW+lh9Ab//0NbJ5XHxRnlYscuOIKs64ss +18disWWFwl5IgCVTPsqqlYZgkwYIdE2FpZdsrKYLDY1T16Qwvs+H0rlRZ5yKY8Xh +j2x+oU8WygSbFPIZ+sONHyfJ4sxjGRdmxohD4roNycwuHqjOZJauw3Mdkl0ibJE0 +oCL5yAf8D7li2aUP/0NRSfb64dfG6RhDH6HQQQIDAQABAoIBAAPOUHJEHS+3iaAb +2/R8oOtYTajuHlEqy9QliVG3XeBSzReUQ5LDcP3gbb3oglABABfQA1fCeRo9y2Jb +nHQfHyK1Y4brTAMY2GgrEzcvD7nPrWVGMfCvre3oIOAji+lQ4A3zohH8nQNMWqRt +e9sYIszzvYE9mshc7q/iavrzlPQsDQhU/yzkW99x95UCw5sqVWXW6ubfIyqphrKC +5Ch7ottruBV1y6CThAZE77O2SR4RRwFKdftXXtXltXAtBvBKq9qpOm5GdY0/zDcK +v75gmLJ4Pom78/+bOp4vVhpYhkCl5aixv2Lpf1Dlvwvaz1FR+HHAFecELLwT29tC +uAi5mQECgYEAwYmGwGGMk97o6rxrQcsobZ44+Hk5FiK8UOmvUlDCWHnJ9GPAkaFH +Lw1+VF4ODnUrOWO55sx15SvYNUfaBieh+jGdBV98zeodETeyc+7DbYkQpaGMRuwl +sMN9pMix0q73TQET9PVholssiT4wUAL5Uy+h04nzUbNzOxLCB93DnhECgYEAwjC9 +1JinezngDFXoFaJ2ta+W25QViNlbJCyBxbuf/UmGbZOrJQAZHIunZHqMGNrgp9ro ++z5QhuKfg1pRSdeGC2TwH0D3GiaWsIeYqb7bIFKWuMXIm3klNdNuR1pXIDiB9sfx +jx//1ol5+BO0SrhXZNua6euy74JhiupKSJnEnzECgYBdYsXhuHBDvdC3y5kZkzT7 +x9gHlT7FfpdNl6TgXFWaqZGYWjXGT4LwolstzICN212zAHrocgoFPeXCt9vtElyn +RB9XQ18OYQQLlcuHA1PLW9LriQsOAc6h/4J1691aItDzmCyQC4ND+yh/RMG9KeIy +kI5Oa4c8ChH1FDUJ5KkKcQKBgHLbd3xGalFFUxKYwTQCquodmEH53Z7ayMClnoBA +0Il0spEfVYwF+dRbeb/BiBmvZE+D+GeaXPDbG/QKOKhPVNZqdmhV+ZG7H0f8e7xy +yZLdpo5VVak3x12F1+VWNtA0/BHmAydfiufu2nhz1yCW1gIurfsL0QM+/8i1eQhm +AtkRAoGAE9moiNCqQPbDVf9LcChzbsgnXsFbwGpzZtw83C8Xf3aKwPWyVXhHS3Sh +xaJu7uZTmwwzXYTfpyraKdYDJNCTupaZqZlj28xqxDN2fYoSwPpuMM0uyKDmZwBk +IX8kptaMRGorPadI+7UEPfgIjtqYXYeJbChscepcqeu87GjSS1o= +-----END rsa private key----- \ No newline at end of file diff --git a/utility/gamelife/gamelife.go b/utility/gamelife/gamelife.go index 269115e..5a817f8 100644 --- a/utility/gamelife/gamelife.go +++ b/utility/gamelife/gamelife.go @@ -88,14 +88,15 @@ func (s *gamelifeClient) GetUserKeyIV(ctx context.Context, popenId string) (cach // base64编码 base64Encode := encrypt.Base64Encode(key) // 向游戏人生发送请求 - result := struct { - secret string `json:"secret"` - key string `json:"key"` // 该用户的token,后续的账号绑定、登录态携带都需要此参数。 - }{} + type httpResult struct { + Secret string `json:"secret"` + Key string `json:"key"` // 该用户的token,后续的账号绑定、登录态携带都需要此参数。 + } + var result httpResult resp, err := resty.New().R().SetBody(map[string]string{ "plat_id": s.PlatId, "key": base64Encode, - }).SetResult(result).Post(s.keyivUrlMap[s.Mode]) + }).SetResult(&result).Post(s.keyivUrlMap[s.Mode]) if err != nil { err = ecode.Fail.Sub("获取用户信息失败") return @@ -107,7 +108,7 @@ func (s *gamelifeClient) GetUserKeyIV(ctx context.Context, popenId string) (cach } - decode, err := encrypt.Base64Decode(result.secret) + decode, err := encrypt.Base64Decode(result.Secret) if err != nil { err = ecode.Fail.Sub("解密用户信息失败") return @@ -121,15 +122,15 @@ func (s *gamelifeClient) GetUserKeyIV(ctx context.Context, popenId string) (cach } aesResult := struct { - key string `json:"key"` - iv string `json:"iv"` + Key string `json:"key"` + IV string `json:"iv"` }{} if err = json.Unmarshal(plain, &aesResult); err != nil { err = ecode.Fail.Sub("解密用户信息失败") return } - gamelifeCache := model.UserGamelifeCache{Aes: aesResult.key, IV: aesResult.iv, Token: result.key} + gamelifeCache := model.UserGamelifeCache{Aes: aesResult.Key, IV: aesResult.IV, Token: result.Key} // 将用户的 aeskey 和 iv 存储到缓存当中,用于后续请求数据加密, 固定时间 2 小时同时不同用户加上一个随机时间 if err = g.Redis().SetEX(ctx, fmt.Sprintf(consts.GameLifeUserKey, popenId), gamelifeCache, int64(consts.GameLifeUserExpire+grand.Intn(1000))); err != nil { err = ecode.Fail.Sub("设置用户信息失败") diff --git a/utility/rsa/rsa.go b/utility/rsa/rsa.go index 6ed2980..6f97154 100644 --- a/utility/rsa/rsa.go +++ b/utility/rsa/rsa.go @@ -7,10 +7,11 @@ import ( "crypto/x509" "encoding/pem" "errors" - "os" - "sync" - + "fmt" "github.com/gogf/gf/v2/frame/g" + "os" + "strings" + "sync" ) type rsaClient struct { @@ -28,7 +29,7 @@ func init() { ctx := context.Background() once.Do(func() { instance = &rsaClient{} - err := instance.loadKeys(g.Config().MustGet(ctx, "rsa.publickey").String(), g.Config().MustGet(ctx, "rsa.privatekey").String()) + err := instance.loadKeys(g.Config().MustGet(ctx, "gamelife.rsaKey").String()) if err != nil { panic("加载 RSA 密钥失败: " + err.Error()) } @@ -80,47 +81,94 @@ func (c *rsaClient) DecryptWithRsaPrivateKey(cipher []byte) ([]byte, error) { // // 返回值: // - 成功返回 nil,否则返回错误信息。 -func (c *rsaClient) loadKeys(publicKeyPath, privateKeyPath string) error { - // 加载公钥 - pubBytes, err := os.ReadFile(publicKeyPath) +func (c *rsaClient) loadKeys(keyFilePath string) error { + // 读取密钥文件 + keyBytes, err := os.ReadFile(keyFilePath) if err != nil { - return err - } - pubBlock, _ := pem.Decode(pubBytes) - if pubBlock == nil { - return errors.New("无法解析公钥 PEM 文件") - } - pubKey, err := x509.ParsePKIXPublicKey(pubBlock.Bytes) - if err != nil { - return err - } - var ok bool - if c.publicKey, ok = pubKey.(*rsa.PublicKey); !ok { - return errors.New("公钥不是 RSA 公钥") + return fmt.Errorf("读取密钥文件失败: %w", err) } - // 加载私钥 - privBytes, err := os.ReadFile(privateKeyPath) - if err != nil { - return err - } - privBlock, _ := pem.Decode(privBytes) - if privBlock == nil { - return errors.New("无法解析私钥 PEM 文件") - } - // 尝试解析 PKCS#8 格式 - privKey, err := x509.ParsePKCS8PrivateKey(privBlock.Bytes) - if err != nil { - // 回退尝试 PKCS#1 格式 - privKey, err = x509.ParsePKCS1PrivateKey(privBlock.Bytes) - if err != nil { - return errors.New("解析私钥失败: 既不是 PKCS#8 也不是 PKCS#1 格式") + var pubFound, privFound bool + rest := keyBytes + + for { + var block *pem.Block + block, rest = pem.Decode(rest) + if block == nil { + break + } + + // 转换为小写以匹配你的密钥格式 + blockTypeLower := strings.ToLower(block.Type) + + switch blockTypeLower { + case "rsa public key": + // 尝试解析 PKCS#1 格式的公钥 + pubKey, err := x509.ParsePKCS1PublicKey(block.Bytes) + if err != nil { + // 尝试 PKIX 格式(兼容性处理) + pub, err := x509.ParsePKIXPublicKey(block.Bytes) + if err != nil { + return fmt.Errorf("无法解析 RSA 公钥: %w", err) + } + var ok bool + if c.publicKey, ok = pub.(*rsa.PublicKey); !ok { + return errors.New("解析的公钥不是 RSA 公钥") + } + } else { + c.publicKey = pubKey + } + pubFound = true + + case "rsa private key": + // 解析 PKCS#1 格式的私钥 + privKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) + if err != nil { + return fmt.Errorf("无法解析 RSA 私钥: %w", err) + } + c.privateKey = privKey + privFound = true + + default: + // 忽略未知的 PEM 块 + continue } } - var ok2 bool - if c.privateKey, ok2 = privKey.(*rsa.PrivateKey); !ok2 { - return errors.New("私钥不是 RSA 私钥") + + if !pubFound { + return errors.New("未找到有效的 RSA 公钥") + } + if !privFound { + return errors.New("未找到有效的 RSA 私钥") } return nil } + +// EncryptWithPublicKey 使用公钥加密数据 +func (c *rsaClient) EncryptWithPublicKey(plaintext []byte) ([]byte, error) { + if c.publicKey == nil { + return nil, errors.New("公钥未加载") + } + + // 使用 OAEP 填充进行加密 + ciphertext, err := rsa.EncryptPKCS1v15(rand.Reader, c.publicKey, plaintext) + if err != nil { + return nil, fmt.Errorf("公钥加密失败: %w", err) + } + return ciphertext, nil +} + +// DecryptWithPrivateKey 使用私钥解密数据 +func (c *rsaClient) DecryptWithPrivateKey(ciphertext []byte) ([]byte, error) { + if c.privateKey == nil { + return nil, errors.New("私钥未加载") + } + + // 使用 OAEP 填充进行解密 + plaintext, err := rsa.DecryptPKCS1v15(rand.Reader, c.privateKey, ciphertext) + if err != nil { + return nil, fmt.Errorf("私钥解密失败: %w", err) + } + return plaintext, nil +}