Files
waf-platform/EdgeNode/internal/encryption/key_generator.go
2026-02-04 20:27:13 +08:00

98 lines
2.0 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
package encryption
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt"
"net"
"time"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
)
// GenerateEncryptionKey 生成加密密钥
// 返回 keyID 和 actualKey
func GenerateEncryptionKey(remoteIP string, userAgent string, policy *serverconfigs.EncryptionKeyPolicy) (keyID string, actualKey string) {
if policy == nil {
policy = serverconfigs.NewEncryptionKeyPolicy()
}
// 1. 时间分片
timeBucket := time.Now().Unix() / policy.TimeBucket
// 2. IP 归一化CIDR
ipPrefix := GetCIDRPrefix(remoteIP, policy.IPCIDR)
// 3. UA 简化
uaHash := userAgent
if policy.UASimplify {
uaHash = serverconfigs.SimplifyUserAgent(userAgent)
}
uaHashValue := sha256.Sum256([]byte(uaHash))
// 4. 生成 KeyID用于缓存
keyID = fmt.Sprintf("%s_%d_%x", ipPrefix, timeBucket, uaHashValue[:8])
// 5. 生成实际密钥HMAC-SHA256
hmacKey := hmac.New(sha256.New, []byte(policy.ServerSecret))
hmacKey.Write([]byte(fmt.Sprintf("%s_%s_%d", ipPrefix, uaHash, timeBucket)))
finalKey := hex.EncodeToString(hmacKey.Sum(nil))
return keyID, finalKey
}
// GetCIDRPrefix 获取 IP 的 CIDR 前缀
func GetCIDRPrefix(ipString string, prefixLen int) string {
ip := net.ParseIP(ipString)
if ip == nil {
return "0.0.0.0"
}
ipv4 := ip.To4()
if ipv4 != nil {
// IPv4
if prefixLen > 32 {
prefixLen = 32
}
if prefixLen < 0 {
prefixLen = 0
}
// 计算掩码
mask := net.CIDRMask(prefixLen, 32)
if mask == nil {
return "0.0.0.0"
}
// 应用掩码
maskedIP := ipv4.Mask(mask)
return maskedIP.String()
}
// IPv6
ipv6 := ip.To16()
if ipv6 != nil {
if prefixLen > 128 {
prefixLen = 128
}
if prefixLen < 0 {
prefixLen = 0
}
// 计算掩码
mask := net.CIDRMask(prefixLen, 128)
if mask == nil {
return "::"
}
// 应用掩码
maskedIP := ipv6.Mask(mask)
return maskedIP.String()
}
return "0.0.0.0"
}