尝试解密数据
This commit is contained in:
parent
f1702b9891
commit
02fdf31829
|
@ -6,17 +6,10 @@ type Empty {}
|
||||||
|
|
||||||
type Req{
|
type Req{
|
||||||
VendorNo string `json:"vendorNo"`
|
VendorNo string `json:"vendorNo"`
|
||||||
Data ReqData `json:"data"`
|
Data string `json:"data"`
|
||||||
Sign string `json:"sign"`
|
Sign string `json:"sign"`
|
||||||
}
|
}
|
||||||
type ReqData{
|
|
||||||
SipOrderNo string `json:"sipOrderNo"`
|
|
||||||
VoucherTag string `json:"voucherTag"`
|
|
||||||
AccountType int32 `json:"accountType"`
|
|
||||||
AccountNo string `json:"accountNo"`
|
|
||||||
AccountInfo string `json:"accountInfo"`
|
|
||||||
Num int `json:"num"`
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,9 @@ package transfer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"rs/rpc/transfer"
|
"rs/rpc/transfer"
|
||||||
|
"rs/untils/rsa"
|
||||||
|
|
||||||
"github.com/jinzhu/copier"
|
"github.com/jinzhu/copier"
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
@ -30,25 +32,61 @@ func (l *MarketLogic) Market(req *types.Req) (resp *types.Resp, err error) {
|
||||||
reqData transfer.RsCouponGrantReq
|
reqData transfer.RsCouponGrantReq
|
||||||
res types.Resp
|
res types.Resp
|
||||||
)
|
)
|
||||||
prefix := req.Data.VoucherTag[0:6]
|
|
||||||
prefixData, err := l.svcCtx.ProductRedirectConf.FindOneByProductNoPrefix(l.ctx, prefix)
|
DecryptData, _ := l.Decrypt(req.VendorNo, req.Data)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
_ = copier.Copy(&reqData, &req)
|
_ = copier.Copy(&reqData, &req)
|
||||||
if prefixData == nil {
|
tagLen := len(DecryptData.VoucherTag)
|
||||||
|
if tagLen > 6 {
|
||||||
|
//如果没有解析出来,直接投递给荣数,让荣数自行处理转发
|
||||||
result, _err := l.svcCtx.TransferRpc.RsCouponGrant(l.ctx, &reqData)
|
result, _err := l.svcCtx.TransferRpc.RsCouponGrant(l.ctx, &reqData)
|
||||||
if _err != nil {
|
if _err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
_ = copier.Copy(&res, &result)
|
_ = copier.Copy(&res, &result)
|
||||||
} else {
|
} else {
|
||||||
result, _err := l.svcCtx.TransferRpc.ZltxRsMiXue(l.ctx, &reqData)
|
prefix := DecryptData.VoucherTag[0:6]
|
||||||
if _err != nil {
|
prefixData, err := l.svcCtx.ProductRedirectConf.FindOneByProductNoPrefix(l.ctx, prefix)
|
||||||
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
_ = copier.Copy(&res, &result)
|
if prefixData == nil {
|
||||||
|
result, _err := l.svcCtx.TransferRpc.RsCouponGrant(l.ctx, &reqData)
|
||||||
|
if _err != nil {
|
||||||
|
return nil, _err
|
||||||
|
}
|
||||||
|
_ = copier.Copy(&res, &result)
|
||||||
|
} else {
|
||||||
|
result, _err := l.svcCtx.TransferRpc.ZltxRsMiXue(l.ctx, &reqData)
|
||||||
|
if _err != nil {
|
||||||
|
return nil, _err
|
||||||
|
}
|
||||||
|
_ = copier.Copy(&res, &result)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &res, nil
|
return &res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *MarketLogic) Decrypt(vendorNo string, encryptData string) (types.DecryptReqData, error) {
|
||||||
|
var (
|
||||||
|
decryptData types.DecryptReqData
|
||||||
|
deCrypt []byte
|
||||||
|
)
|
||||||
|
merchantInfo, err := l.svcCtx.Merchant.FindOneByMerchantId(l.ctx, vendorNo)
|
||||||
|
if err != nil {
|
||||||
|
return decryptData, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改请求体
|
||||||
|
switch merchantInfo.SignatureMethod {
|
||||||
|
default:
|
||||||
|
privateKeyPEM := `-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
` + merchantInfo.RsaPrivateKey.String + `
|
||||||
|
-----END RSA PRIVATE KEY-----`
|
||||||
|
deCrypt, err = rsa.Decrypt(privateKeyPEM, encryptData)
|
||||||
|
if err != nil {
|
||||||
|
return decryptData, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ = json.Unmarshal(deCrypt, &decryptData)
|
||||||
|
return decryptData, nil
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
package middleware
|
||||||
|
|
||||||
|
import (
|
||||||
|
"rs/cmd/api/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DecryptMiddleware struct {
|
||||||
|
svcCtx *types.BaseServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDecryptMiddleware(svcCtx *types.BaseServiceContext) *DecryptMiddleware {
|
||||||
|
return &DecryptMiddleware{
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type BaseReq struct {
|
||||||
|
VendorNo string `json:"vendorNo"`
|
||||||
|
Data string `json:"data"`
|
||||||
|
Sign string `json:"sign"`
|
||||||
|
DecryptData string `json:"decrypt_data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
//func (m *DecryptMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
|
||||||
|
// return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// var (
|
||||||
|
// baseReq BaseReq
|
||||||
|
// deCrypt []byte
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
// body, err := io.ReadAll(r.Body)
|
||||||
|
//
|
||||||
|
// defer r.Body.Close()
|
||||||
|
// _ = json.Unmarshal(body, &baseReq)
|
||||||
|
//
|
||||||
|
// baseReq.DecryptData = string(deCrypt)
|
||||||
|
// baseReqJson, _ := json.Marshal(baseReq)
|
||||||
|
// r.Body = io.NopCloser(bytes.NewReader(baseReqJson))
|
||||||
|
// // 创建一个新的Reader并设置为请求的Body
|
||||||
|
// next(w, r)
|
||||||
|
// }
|
||||||
|
//}
|
|
@ -2,27 +2,33 @@ package svc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
"github.com/zeromicro/go-zero/zrpc"
|
"github.com/zeromicro/go-zero/rest"
|
||||||
"rs/cmd/api/internal/config"
|
"rs/cmd/api/internal/config"
|
||||||
|
"rs/cmd/api/internal/types"
|
||||||
"rs/genModel"
|
"rs/genModel"
|
||||||
"rs/rpc/transferClient"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type ServiceContext struct {
|
type ServiceContext struct {
|
||||||
Config config.Config
|
*types.BaseServiceContext
|
||||||
TransferRpc transferClient.Transfer // 调用transfer服务
|
DecryptMiddleware rest.Middleware
|
||||||
ProductRedirectConf genModel.ProductRedirectConfModel
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServiceContext(c config.Config) *ServiceContext {
|
func NewServiceContext(c config.Config) *ServiceContext {
|
||||||
conn := zrpc.MustNewClient(zrpc.RpcClientConf{
|
//conn := zrpc.MustNewClient(zrpc.RpcClientConf{
|
||||||
Target: c.Nacos.Target,
|
// Target: c.Nacos.Target,
|
||||||
})
|
//})
|
||||||
sqlConn := sqlx.NewMysql(c.DB.Coupon.DataSource)
|
sqlConn := sqlx.NewMysql(c.DB.Coupon.DataSource)
|
||||||
client := transferClient.NewTransfer(conn)
|
//client := transferClient.NewTransfer(conn)
|
||||||
return &ServiceContext{
|
|
||||||
Config: c,
|
base := types.BaseServiceContext{
|
||||||
TransferRpc: client,
|
Config: c,
|
||||||
|
//TransferRpc: client,
|
||||||
ProductRedirectConf: genModel.NewProductRedirectConfModel(sqlConn, c.Cache),
|
ProductRedirectConf: genModel.NewProductRedirectConfModel(sqlConn, c.Cache),
|
||||||
|
Merchant: genModel.NewMerchantModel(sqlConn, c.Cache),
|
||||||
}
|
}
|
||||||
|
return &ServiceContext{
|
||||||
|
BaseServiceContext: &base,
|
||||||
|
//DecryptMiddleware: middleware.NewDecryptMiddleware(&base).Handle,
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"rs/cmd/api/internal/config"
|
||||||
|
"rs/genModel"
|
||||||
|
"rs/rpc/transferClient"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BaseServiceContext struct {
|
||||||
|
Config config.Config
|
||||||
|
TransferRpc transferClient.Transfer // 调用transfer服务
|
||||||
|
ProductRedirectConf genModel.ProductRedirectConfModel
|
||||||
|
Merchant genModel.MerchantModel
|
||||||
|
}
|
||||||
|
|
||||||
|
type DecryptReqData struct {
|
||||||
|
SipOrderNo string `json:"sipOrderNo"`
|
||||||
|
VoucherTag string `json:"voucherTag"`
|
||||||
|
AccountType int32 `json:"accountType"`
|
||||||
|
AccountNo string `json:"accountNo"`
|
||||||
|
AccountInfo string `json:"accountInfo,optional"`
|
||||||
|
Num int `json:"num"`
|
||||||
|
}
|
|
@ -5,18 +5,9 @@ type Empty struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Req struct {
|
type Req struct {
|
||||||
VendorNo string `json:"vendorNo"`
|
VendorNo string `json:"vendorNo"`
|
||||||
Data ReqData `json:"data"`
|
Data string `json:"data"`
|
||||||
Sign string `json:"sign"`
|
Sign string `json:"sign"`
|
||||||
}
|
|
||||||
|
|
||||||
type ReqData struct {
|
|
||||||
SipOrderNo string `json:"sipOrderNo"`
|
|
||||||
VoucherTag string `json:"voucherTag"`
|
|
||||||
AccountType int32 `json:"accountType"`
|
|
||||||
AccountNo string `json:"accountNo"`
|
|
||||||
AccountInfo string `json:"accountInfo"`
|
|
||||||
Num int `json:"num"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Resp struct {
|
type Resp struct {
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
package genModel
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/cache"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ MerchantModel = (*customMerchantModel)(nil)
|
||||||
|
|
||||||
|
type (
|
||||||
|
// MerchantModel is an interface to be customized, add more methods here,
|
||||||
|
// and implement the added methods in customMerchantModel.
|
||||||
|
MerchantModel interface {
|
||||||
|
merchantModel
|
||||||
|
}
|
||||||
|
|
||||||
|
customMerchantModel struct {
|
||||||
|
*defaultMerchantModel
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewMerchantModel returns a model for the database table.
|
||||||
|
func NewMerchantModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) MerchantModel {
|
||||||
|
return &customMerchantModel{
|
||||||
|
defaultMerchantModel: newMerchantModel(conn, c, opts...),
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,160 @@
|
||||||
|
// Code generated by goctl. DO NOT EDIT.
|
||||||
|
|
||||||
|
package genModel
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/builder"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/cache"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlc"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
"github.com/zeromicro/go-zero/core/stringx"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
merchantFieldNames = builder.RawFieldNames(&Merchant{})
|
||||||
|
merchantRows = strings.Join(merchantFieldNames, ",")
|
||||||
|
merchantRowsExpectAutoSet = strings.Join(stringx.Remove(merchantFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
|
||||||
|
merchantRowsWithPlaceHolder = strings.Join(stringx.Remove(merchantFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?"
|
||||||
|
|
||||||
|
cacheCouponOpenMerchantIdPrefix = "cache:couponOpen:merchant:id:"
|
||||||
|
cacheCouponOpenMerchantMerchantIdPrefix = "cache:couponOpen:merchant:merchantId:"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
merchantModel interface {
|
||||||
|
Insert(ctx context.Context, data *Merchant) (sql.Result, error)
|
||||||
|
FindOne(ctx context.Context, id uint64) (*Merchant, error)
|
||||||
|
FindOneByMerchantId(ctx context.Context, merchantId string) (*Merchant, error)
|
||||||
|
Update(ctx context.Context, data *Merchant) error
|
||||||
|
Delete(ctx context.Context, id uint64) error
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultMerchantModel struct {
|
||||||
|
sqlc.CachedConn
|
||||||
|
table string
|
||||||
|
}
|
||||||
|
|
||||||
|
Merchant struct {
|
||||||
|
Id uint64 `db:"id"`
|
||||||
|
MerchantId string `db:"merchant_id"` // 商户号
|
||||||
|
FullName string `db:"full_name"` // 商户全称
|
||||||
|
Status int64 `db:"status"` // 状态 1可用 2禁用
|
||||||
|
SignatureMethod uint64 `db:"signature_method"` // 签名方式1 Rsa2 2 Sm
|
||||||
|
RsaPublicKey sql.NullString `db:"rsa_public_key"` // rsa公钥
|
||||||
|
RsaPrivateKey sql.NullString `db:"rsa_private_key"` // rsa私钥
|
||||||
|
MchRsaPublicKey sql.NullString `db:"mch_rsa_public_key"`
|
||||||
|
Sm2PublicKey sql.NullString `db:"sm2_public_key"` // 国密sm2公钥
|
||||||
|
Sm2PrivateKey sql.NullString `db:"sm2_private_key"` // 国密sm2私钥
|
||||||
|
MchSm2PublicKey sql.NullString `db:"mch_sm2_public_key"` // 商户侧国密sm2公钥
|
||||||
|
Sm4SecretKey sql.NullString `db:"sm4_secret_key"` // 国密sm4报文加密密钥
|
||||||
|
IpAccess sql.NullString `db:"ip_access"` // ip白名单["192.168.6.18"]
|
||||||
|
RequestRate sql.NullString `db:"request_rate"` // 请求频率限制{ "default": "500", "wechat_coupon_send" : "500"}
|
||||||
|
UpdateTime sql.NullTime `db:"update_time"` // 更新时间
|
||||||
|
CreateTime time.Time `db:"create_time"` // 创建时间
|
||||||
|
Password string `db:"password"` // 登陆密码
|
||||||
|
Phone sql.NullString `db:"phone"` // 手机号
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func newMerchantModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) *defaultMerchantModel {
|
||||||
|
return &defaultMerchantModel{
|
||||||
|
CachedConn: sqlc.NewConn(conn, c, opts...),
|
||||||
|
table: "`merchant`",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultMerchantModel) Delete(ctx context.Context, id uint64) error {
|
||||||
|
data, err := m.FindOne(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
couponOpenMerchantIdKey := fmt.Sprintf("%s%v", cacheCouponOpenMerchantIdPrefix, id)
|
||||||
|
couponOpenMerchantMerchantIdKey := fmt.Sprintf("%s%v", cacheCouponOpenMerchantMerchantIdPrefix, data.MerchantId)
|
||||||
|
_, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||||
|
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
|
||||||
|
return conn.ExecCtx(ctx, query, id)
|
||||||
|
}, couponOpenMerchantIdKey, couponOpenMerchantMerchantIdKey)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultMerchantModel) FindOne(ctx context.Context, id uint64) (*Merchant, error) {
|
||||||
|
couponOpenMerchantIdKey := fmt.Sprintf("%s%v", cacheCouponOpenMerchantIdPrefix, id)
|
||||||
|
var resp Merchant
|
||||||
|
err := m.QueryRowCtx(ctx, &resp, couponOpenMerchantIdKey, func(ctx context.Context, conn sqlx.SqlConn, v any) error {
|
||||||
|
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", merchantRows, m.table)
|
||||||
|
return conn.QueryRowCtx(ctx, v, query, id)
|
||||||
|
})
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return &resp, nil
|
||||||
|
case sqlc.ErrNotFound:
|
||||||
|
return nil, ErrNotFound
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultMerchantModel) FindOneByMerchantId(ctx context.Context, merchantId string) (*Merchant, error) {
|
||||||
|
couponOpenMerchantMerchantIdKey := fmt.Sprintf("%s%v", cacheCouponOpenMerchantMerchantIdPrefix, merchantId)
|
||||||
|
var resp Merchant
|
||||||
|
err := m.QueryRowIndexCtx(ctx, &resp, couponOpenMerchantMerchantIdKey, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v any) (i any, e error) {
|
||||||
|
query := fmt.Sprintf("select %s from %s where `merchant_id` = ? limit 1", merchantRows, m.table)
|
||||||
|
if err := conn.QueryRowCtx(ctx, &resp, query, merchantId); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return resp.Id, nil
|
||||||
|
}, m.queryPrimary)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return &resp, nil
|
||||||
|
case sqlc.ErrNotFound:
|
||||||
|
return nil, ErrNotFound
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultMerchantModel) Insert(ctx context.Context, data *Merchant) (sql.Result, error) {
|
||||||
|
couponOpenMerchantIdKey := fmt.Sprintf("%s%v", cacheCouponOpenMerchantIdPrefix, data.Id)
|
||||||
|
couponOpenMerchantMerchantIdKey := fmt.Sprintf("%s%v", cacheCouponOpenMerchantMerchantIdPrefix, data.MerchantId)
|
||||||
|
ret, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||||
|
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, merchantRowsExpectAutoSet)
|
||||||
|
return conn.ExecCtx(ctx, query, data.MerchantId, data.FullName, data.Status, data.SignatureMethod, data.RsaPublicKey, data.RsaPrivateKey, data.MchRsaPublicKey, data.Sm2PublicKey, data.Sm2PrivateKey, data.MchSm2PublicKey, data.Sm4SecretKey, data.IpAccess, data.RequestRate, data.Password, data.Phone)
|
||||||
|
}, couponOpenMerchantIdKey, couponOpenMerchantMerchantIdKey)
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultMerchantModel) Update(ctx context.Context, newData *Merchant) error {
|
||||||
|
data, err := m.FindOne(ctx, newData.Id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
couponOpenMerchantIdKey := fmt.Sprintf("%s%v", cacheCouponOpenMerchantIdPrefix, data.Id)
|
||||||
|
couponOpenMerchantMerchantIdKey := fmt.Sprintf("%s%v", cacheCouponOpenMerchantMerchantIdPrefix, data.MerchantId)
|
||||||
|
_, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||||
|
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, merchantRowsWithPlaceHolder)
|
||||||
|
return conn.ExecCtx(ctx, query, newData.MerchantId, newData.FullName, newData.Status, newData.SignatureMethod, newData.RsaPublicKey, newData.RsaPrivateKey, newData.MchRsaPublicKey, newData.Sm2PublicKey, newData.Sm2PrivateKey, newData.MchSm2PublicKey, newData.Sm4SecretKey, newData.IpAccess, newData.RequestRate, newData.Password, newData.Phone, newData.Id)
|
||||||
|
}, couponOpenMerchantIdKey, couponOpenMerchantMerchantIdKey)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultMerchantModel) formatPrimary(primary any) string {
|
||||||
|
return fmt.Sprintf("%s%v", cacheCouponOpenMerchantIdPrefix, primary)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultMerchantModel) queryPrimary(ctx context.Context, conn sqlx.SqlConn, v, primary any) error {
|
||||||
|
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", merchantRows, m.table)
|
||||||
|
return conn.QueryRowCtx(ctx, v, query, primary)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultMerchantModel) tableName() string {
|
||||||
|
return m.table
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ option go_package="./transfer";
|
||||||
|
|
||||||
message DefaultRes {
|
message DefaultRes {
|
||||||
string code=1;
|
string code=1;
|
||||||
|
|
||||||
string message=2;
|
string message=2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,15 +37,15 @@ service Transfer {
|
||||||
|
|
||||||
message RsCouponGrantReq {
|
message RsCouponGrantReq {
|
||||||
string vendorNo = 1;
|
string vendorNo = 1;
|
||||||
Data data = 2;
|
string data = 2;
|
||||||
message Data{
|
// message Data{
|
||||||
string sipOrderNo = 1;
|
// string sipOrderNo = 1;
|
||||||
string voucherTag = 2;
|
// string voucherTag = 2;
|
||||||
int32 accountType = 3;
|
// int32 accountType = 3;
|
||||||
string accountNo = 4;
|
// string accountNo = 4;
|
||||||
string accountInfo = 5;
|
// string accountInfo = 5;
|
||||||
int32 num = 6;
|
// int32 num = 6;
|
||||||
}
|
// }
|
||||||
string sign = 3;
|
string sign = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +150,8 @@ message MarketKeySendReq {
|
||||||
|
|
||||||
message ZltxRechargeProductRes {
|
message ZltxRechargeProductRes {
|
||||||
string code=1;
|
string code=1;
|
||||||
repeated Product products=2;
|
string message=2;
|
||||||
|
repeated Product products=3;
|
||||||
message Product{
|
message Product{
|
||||||
int64 productId=1;
|
int64 productId=1;
|
||||||
string channelPrice=2;
|
string channelPrice=2;
|
||||||
|
@ -171,7 +173,7 @@ message ZltxOrderSmsRes {
|
||||||
}
|
}
|
||||||
|
|
||||||
message ZltxOrderSmsReq {
|
message ZltxOrderSmsReq {
|
||||||
string merchantId = 1;
|
int64 merchantId = 1;
|
||||||
uint64 timeStamp = 2;
|
uint64 timeStamp = 2;
|
||||||
string sign = 3;
|
string sign = 3;
|
||||||
string outTradeNo = 4;
|
string outTradeNo = 4;
|
||||||
|
@ -185,14 +187,14 @@ message ZltxOrderCardQueryRes {
|
||||||
string outTradeNo=4;
|
string outTradeNo=4;
|
||||||
}
|
}
|
||||||
message ZltxOrderCardQueryReq {
|
message ZltxOrderCardQueryReq {
|
||||||
string merchantId = 1;
|
int64 merchantId = 1;
|
||||||
uint64 timeStamp = 2;
|
uint64 timeStamp = 2;
|
||||||
string sign = 3;
|
string sign = 3;
|
||||||
string outTradeNo = 4;
|
string outTradeNo = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ZltxOrderCardReq {
|
message ZltxOrderCardReq {
|
||||||
string merchantId = 1;
|
int64 merchantId = 1;
|
||||||
string sign = 2;
|
string sign = 2;
|
||||||
uint64 timeStamp = 3;
|
uint64 timeStamp = 3;
|
||||||
string outTradeNo = 4;
|
string outTradeNo = 4;
|
||||||
|
@ -215,46 +217,21 @@ message ZltxOrderRechargeQueryRes {
|
||||||
string outTradeNo=4;
|
string outTradeNo=4;
|
||||||
}
|
}
|
||||||
message ZltxOrderRechargeQueryReq {
|
message ZltxOrderRechargeQueryReq {
|
||||||
string merchantId = 1;
|
uint64 merchantId = 1;
|
||||||
uint64 timeStamp = 2;
|
uint64 timeStamp = 2;
|
||||||
string sign = 3;
|
string sign = 3;
|
||||||
string outTradeNo = 4;
|
string outTradeNo = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ZltxOrderRechargeReq {
|
message ZltxOrderRechargeReq {
|
||||||
string merchantId = 1;
|
uint64 merchantId = 1;
|
||||||
string sign = 2;
|
string sign = 2;
|
||||||
uint64 timeStamp = 3;
|
uint64 timeStamp = 3;
|
||||||
string outTradeNo = 4;
|
string outTradeNo = 4;
|
||||||
int64 productId=5;
|
int64 productId=5;
|
||||||
string mobile=6;
|
string rechargeAccount=6;
|
||||||
uint32 accountType=7;
|
uint32 accountType=7;
|
||||||
int32 number=8;
|
int32 number=8;
|
||||||
string notifyUrl=9;
|
string notifyUrl=9;
|
||||||
string extendParameter=10;
|
string extendParameter=10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
message GetResellerByAppIdReq {
|
|
||||||
string appId = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message GetResellerByAppIdRes {
|
|
||||||
int64 id=1;
|
|
||||||
string merchantId=2;
|
|
||||||
string resellerId=3;
|
|
||||||
string appId=4;
|
|
||||||
string posId=5;
|
|
||||||
string storeId=6;
|
|
||||||
int32 apiMod=7;
|
|
||||||
string publicKey=8;
|
|
||||||
string privateKey=9;
|
|
||||||
string merchantPublicKey=10;
|
|
||||||
string secretKey=11;
|
|
||||||
string notifyUrl=12;
|
|
||||||
string subscribeEvent=13;
|
|
||||||
int32 status=14;
|
|
||||||
string createTime=15;
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
|
@ -15,8 +15,6 @@ import (
|
||||||
type (
|
type (
|
||||||
DefaultReq = transfer.DefaultReq
|
DefaultReq = transfer.DefaultReq
|
||||||
DefaultRes = transfer.DefaultRes
|
DefaultRes = transfer.DefaultRes
|
||||||
GetResellerByAppIdReq = transfer.GetResellerByAppIdReq
|
|
||||||
GetResellerByAppIdRes = transfer.GetResellerByAppIdRes
|
|
||||||
MarketKeyDiscardReq = transfer.MarketKeyDiscardReq
|
MarketKeyDiscardReq = transfer.MarketKeyDiscardReq
|
||||||
MarketKeyDiscardRes = transfer.MarketKeyDiscardRes
|
MarketKeyDiscardRes = transfer.MarketKeyDiscardRes
|
||||||
MarketKeyDiscardRes_Data = transfer.MarketKeyDiscardRes_Data
|
MarketKeyDiscardRes_Data = transfer.MarketKeyDiscardRes_Data
|
||||||
|
@ -27,7 +25,6 @@ type (
|
||||||
MarketQueryRes = transfer.MarketQueryRes
|
MarketQueryRes = transfer.MarketQueryRes
|
||||||
MarketQueryRes_Data = transfer.MarketQueryRes_Data
|
MarketQueryRes_Data = transfer.MarketQueryRes_Data
|
||||||
RsCouponGrantReq = transfer.RsCouponGrantReq
|
RsCouponGrantReq = transfer.RsCouponGrantReq
|
||||||
RsCouponGrantReq_Data = transfer.RsCouponGrantReq_Data
|
|
||||||
RsCouponGrantRes = transfer.RsCouponGrantRes
|
RsCouponGrantRes = transfer.RsCouponGrantRes
|
||||||
RsCouponGrantRes_Data = transfer.RsCouponGrantRes_Data
|
RsCouponGrantRes_Data = transfer.RsCouponGrantRes_Data
|
||||||
RsCouponGrantRes_Data_VoucherInfo = transfer.RsCouponGrantRes_Data_VoucherInfo
|
RsCouponGrantRes_Data_VoucherInfo = transfer.RsCouponGrantRes_Data_VoucherInfo
|
||||||
|
|
|
@ -7,9 +7,12 @@ V_REFLECT=""
|
||||||
|
|
||||||
docker build -t "${IMAGE}" . --no-cache
|
docker build -t "${IMAGE}" . --no-cache
|
||||||
|
|
||||||
|
|
||||||
docker stop "${CONTAINER}"
|
docker stop "${CONTAINER}"
|
||||||
|
|
||||||
docker rm "${CONTAINER}"
|
docker rm "${CONTAINER}"
|
||||||
|
|
||||||
docker run -it -p "${API_PORT}:${API_PORT}" --name "$CONTAINER" "${IMAGE}"
|
docker run -it -p "${API_PORT}:${API_PORT}" --name "$CONTAINER" "${IMAGE}"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
docker run -it -p "10101:10101" --name "transfer_rs" "transfer_rs:v1"
|
|
@ -0,0 +1 @@
|
||||||
|
package market
|
|
@ -0,0 +1,111 @@
|
||||||
|
package rsa
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/sha256"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/pem"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// parseRSAPublicKeyFromPEM 解析PEM编码的RSA公钥
|
||||||
|
func parseRSAPublicKeyFromPEM(pemData []byte) (*rsa.PublicKey, error) {
|
||||||
|
block, _ := pem.Decode(pemData)
|
||||||
|
if block == nil || block.Type != "PUBLIC KEY" {
|
||||||
|
return nil, fmt.Errorf("failed to parse PEM block containing the RSA public key")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch pub := pub.(type) {
|
||||||
|
case *rsa.PublicKey:
|
||||||
|
return pub, nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unknown public key type in PKIX wrapping")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// encrypt 使用RSA公钥加密数据
|
||||||
|
func Encrypt(publicKeyPEM string, plaintext []byte) ([]byte, error) {
|
||||||
|
// 将PEM编码的公钥转换为[]byte
|
||||||
|
pemData := []byte(publicKeyPEM)
|
||||||
|
|
||||||
|
// 解析PEM数据以获取公钥
|
||||||
|
pubKey, err := parseRSAPublicKeyFromPEM(pemData)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建用于加密的随机填充
|
||||||
|
label := []byte("") // OAEP标签,对于某些情况可能是非空的
|
||||||
|
ciphertext, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, pubKey, plaintext, label)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ciphertext, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseRSAPrivateKeyFromPEM 解析PEM编码的RSA私钥
|
||||||
|
func parseRSAPrivateKeyFromPEM(pemData []byte) (*rsa.PrivateKey, error) {
|
||||||
|
block, _ := pem.Decode(pemData)
|
||||||
|
if block == nil || block.Type != "RSA PRIVATE KEY" {
|
||||||
|
return nil, fmt.Errorf("failed to parse PEM block containing the RSA private key")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 尝试使用PKCS#1 v1.5
|
||||||
|
priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
|
||||||
|
if err != nil {
|
||||||
|
// 如果失败,尝试使用PKCS#8
|
||||||
|
privInterface, err := x509.ParsePKCS8PrivateKey(block.Bytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch k := privInterface.(type) {
|
||||||
|
case *rsa.PrivateKey:
|
||||||
|
priv = k
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unknown private key type in PKCS#8 wrapping")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return priv, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// decrypt 使用RSA私钥解密数据
|
||||||
|
func Decrypt(privateKeyPEM string, encryptedDataBase64 string) ([]byte, error) {
|
||||||
|
// 将PEM编码的私钥转换为[]byte
|
||||||
|
pemData := []byte(privateKeyPEM)
|
||||||
|
|
||||||
|
// 解析PEM数据以获取私钥
|
||||||
|
privKey, err := parseRSAPrivateKeyFromPEM(pemData)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将Base64编码的加密数据解码为字节切片
|
||||||
|
encryptedData, err := base64.StdEncoding.DecodeString(encryptedDataBase64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据你的加密方式选择合适的解密函数
|
||||||
|
// 这里假设使用的是OAEP填充和SHA-256哈希函数
|
||||||
|
label := []byte("") // OAEP标签,对于某些情况可能是非空的
|
||||||
|
decrypted, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, privKey, encryptedData, label)
|
||||||
|
if err != nil {
|
||||||
|
// 如果失败,可以尝试使用PKCS#1 v1.5填充
|
||||||
|
decrypted, err = rsa.DecryptPKCS1v15(rand.Reader, privKey, encryptedData)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return decrypted, nil
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package rsa
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
const prik = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCmjK6SPkrP03ssex5Dxn4KZeVm9rQoJMslru13GNgoGKJAq13xwUGl6lpGlhzM9IMzg0ldOO2a0SQPPjc0fLrDjIgHPfIT6H1hDGkZdPaF4D0OfiHGzlLwXq7FyyyGc2JXILsniMBXcCxNFhbW0jAaJyYrBJb3q84a5y5AtK3IC+eDV6Bj2J4HlQVGKgW9u2ic6Jxl23sacXY6iifi+KEuoXNCJrmYlgRWTaQovLmTCLkErkzxzG9DFRDWGoz25LthDPqcCSUmWEbJ+obwIGB4r2WCbFXvaeVBQORlyVRyNUvYMItjHBQIKinDWZ6y8KzA0YKOoxEfr0KfE8Uk4PQBAgMBAAECggEABTAX0PzelN4uyvTT0sMi/R0YRKPgepP40vtBsNvF10E7Lp4ClAupHpYFSrJq178xu1/2dVBXEGM9hw8GUQd7RCjuD3cFwcp/EKU+Zy6uQ38iZRTskEDa3bC+q3EXzuFXDxqOfIhai262UTlkATw0sjUwJRdkbMxoeWHkSNuH7UBVddxFL8Bq1DKaPzRCqQ8zlkMZHy8Xbf2b8rFoi1oPBoPjHyxCo33zcnSg5xntIoA5pkD6x4z5cAnU55aBoYUiRv7jmG+MVp1jpDvAmJLfUayVZNakgX1r74bMPsl9kpA7dVdgOlWrIkbJE1plVXXswBb8QKN0/Yx2vv/YASSi0QKBgQDaO9BkRjvht/lrsQEur1wXf5ITnsVWsqlUhYQKGHihzOj7e0rGO9QICM4eQZH9ssHfxEXhmEoFdkaqo3Fo47NI+yinpWm+KruwrRFkCGejlKZ4bhn9zWPb8L1qJbN4UD1c5jUNk1B0EEdnLRFg0/O7xm602bGilvY5x2nf0v95+QKBgQDDXyiiGNV7GO4h8OQYJwq0IqenPyIanRgYI3rw//tg147mhWcxT6ms6dMUh9nEXEFali2J1En+aVvx1Xn47CuGrRmZOLaGkw9ESFA/4ngYdea+xgttbKMXm0QwIwvATq2jxxrYEKmnr/+EUUWzIWioM1zQffAhVlkLFVnImquMSQKBgDe7qNfC/A4ELwWqubOTg0BZCxRJqvoePJJiWrs9Tql7rFB1Rz5jDx5SKVmew0r4OP0Nog8gFl9YumlfvlncNPBBfDt8SgoP3ckcGeHjJ5ymHPGKpMaliogj7ivKnw/t5g3wmMHzyksp0SJvZw3Ec22UGrfDFNOCHDXbUJWhzC75AoGBALbM6rAAnH65LNcFFeajYRh69HNAVyCfrFOpnvawDPzntAVs/MjeyNvJTH8BPXjE+UFREvrLbxBkdGsqWx3VnEQ+4pzCu8XfA4HYR33+4G/CoUwO8dJIu7DyzjJcGDqvYzjCqxNPQ+5qdqHPiW+56rq2lDlgHLaUnGwKZh+U2L5BAoGAeogtSQbnZaLQofSGcUOol2fyG24NU1JK3My+N1ypkSpD+y1KiFQeM5kg7UcJB6LBKZ/lRCKcjEMaxMyj57ETMkbRVKBLvsIL5QYolJLIHYqBul0AeFJ4K51SKK2Xk5rFvyuJKkJBux26WodtCXTnEzP1KRZGlSxJeN/V1yXjSEU="
|
||||||
|
|
||||||
|
const pubk = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApoyukj5Kz9N7LHseQ8Z+CmXlZva0KCTLJa7tdxjYKBiiQKtd8cFBpepaRpYczPSDM4NJXTjtmtEkDz43NHy6w4yIBz3yE+h9YQxpGXT2heA9Dn4hxs5S8F6uxcsshnNiVyC7J4jAV3AsTRYW1tIwGicmKwSW96vOGucuQLStyAvng1egY9ieB5UFRioFvbtonOicZdt7GnF2Ooon4vihLqFzQia5mJYEVk2kKLy5kwi5BK5M8cxvQxUQ1hqM9uS7YQz6nAklJlhGyfqG8CBgeK9lgmxV72nlQUDkZclUcjVL2DCLYxwUCCopw1mesvCswNGCjqMRH69CnxPFJOD0AQIDAQAB"
|
||||||
|
|
||||||
|
func Test_en(t *testing.T) {
|
||||||
|
data := make(map[string]interface{}, 2)
|
||||||
|
data["a"] = 1
|
||||||
|
data["b"] = "sdadas"
|
||||||
|
dataJson, _ := json.Marshal(data)
|
||||||
|
pub := `-----BEGIN PUBLIC KEY-----
|
||||||
|
` + pubk + `
|
||||||
|
-----END PUBLIC KEY-----`
|
||||||
|
res, err := Encrypt(pub, dataJson)
|
||||||
|
fmt.Println(base64.StdEncoding.EncodeToString(res), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_de(t *testing.T) {
|
||||||
|
data := "oSpZJFBORDtJDpKjk5q4C1ex7CbgDW+YjMS7gCQHIsn1dgrSXEvjgeuA2jhc29CstkIDjwQ/qhInXVl/M9hphB9oujfegD+FPRspRhDrBY1csuPLDiKZh82LQfPMMXCQcZk73F+OfHl9cX/QLi/2uRUw3UsEO8Hv6o9VM1mSkg+uWAqqFKZKvVXJBTNHRzlQ56LTMZG8kwGGQisoCvi+f+6B/3Kd9co+csMAEeE+gK/Ix+c8jLs5lL8QKZW9vALa8zgTPG3oicxIYHqNoPqc8Z/R+C69k30QRsbWhyixPpSGxGkV9Pvy8czj/t+uoDiZ7hOQugR9ss7DIwZHuyDcHA=="
|
||||||
|
privateKeyPEM := `-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
` + prik + `
|
||||||
|
-----END RSA PRIVATE KEY-----`
|
||||||
|
res, err := Decrypt(privateKeyPEM, data)
|
||||||
|
fmt.Println(string(res), err)
|
||||||
|
}
|
Loading…
Reference in New Issue