优化与代理服务的密钥存储与传递方式;更新套餐,账单查询对长效套餐的支持,新增长效套餐分页查询接口

This commit is contained in:
2025-05-22 14:55:04 +08:00
parent 6f1bc72912
commit 15ffccf554
7 changed files with 308 additions and 81 deletions

View File

@@ -1,6 +1,11 @@
package globals
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/base32"
"encoding/base64"
"encoding/json"
"fmt"
"net/http"
@@ -29,15 +34,19 @@ type ProxyPermitConfig struct {
Expire time.Time `json:"expire"`
}
func (p *ProxyClient) Permit(proxy string, config []*ProxyPermitConfig) error {
func (p *ProxyClient) Permit(host string, secret string, config []*ProxyPermitConfig) error {
str, err := json.Marshal(config)
// 请求体加密
body, err := encrypt(config, secret)
if err != nil {
return err
return fmt.Errorf("加密请求失败: %w", err)
}
body := strings.NewReader(string(str))
resp, err := http.Post(fmt.Sprintf("%s:8848%s", proxy, PermitEndpoint), "application/json", body)
resp, err := http.Post(
fmt.Sprintf("http://%s:8848%s", host, PermitEndpoint),
"application/json",
strings.NewReader(body),
)
if err != nil {
return err
}
@@ -49,3 +58,61 @@ func (p *ProxyClient) Permit(proxy string, config []*ProxyPermitConfig) error {
return nil
}
func encrypt(req []*ProxyPermitConfig, secretStr string) (string, error) {
var encoding = base32.StdEncoding.WithPadding(base32.NoPadding)
// 创建 AES 密钥
secret, err := encoding.DecodeString(secretStr)
if err != nil {
return "", fmt.Errorf("解码 AES 密钥字符串失败: %w", err)
}
block, err := aes.NewCipher(secret)
if err != nil {
return "", fmt.Errorf("创建 AES 密钥失败: %w", err)
}
gcm, err := cipher.NewGCM(block)
if err != nil {
return "", fmt.Errorf("创建 AES GCM 失败: %w", err)
}
// 加密内容
bytes, err := json.Marshal(req)
if err != nil {
return "", fmt.Errorf("配置参数序列化失败: %w", err)
}
nonceBytes := make([]byte, gcm.NonceSize())
if _, err := rand.Read(nonceBytes); err != nil {
return "", fmt.Errorf("生成随机数失败: %w", err)
}
nonce := base32.StdEncoding.WithPadding(base32.NoPadding).EncodeToString(nonceBytes)
timestamp := time.Now().UnixMilli()
aad := fmt.Sprintf("%s:%d", nonce, timestamp)
ciphertext := gcm.Seal(nil, nonceBytes, bytes, []byte(aad))
encoded := base64.StdEncoding.EncodeToString(ciphertext)
// 生成请求体
encrypted := EncryptReq{
Content: encoded,
Nonce: nonce,
Timestamp: timestamp,
}
body, err := json.Marshal(encrypted)
if err != nil {
return "", fmt.Errorf("请求参数序列化失败: %w", err)
}
return string(body), nil
}
type EncryptReq struct {
Content string `json:"content"`
Nonce string `json:"nonce"`
Timestamp int64 `json:"timestamp"`
}