b64_PSK
This commit is contained in:
@@ -3,8 +3,10 @@ package xboard
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/md5"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@@ -27,17 +29,19 @@ import (
|
|||||||
"github.com/sagernet/sing/service"
|
"github.com/sagernet/sing/service"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ss2022UserKey prepares a user key for SS2022:
|
// ss2022Key derives a secure 2022 key from a seed string (like UUID or ServerKey).
|
||||||
// Truncate UUID string to keyLen and encode as Base64 for sing-box.
|
// Logic: base64(hex(md5(seed)))[:keyLen] -- this is a common panel pattern.
|
||||||
func ss2022UserKey(identity string, keyLen int) string {
|
func ss2022Key(seed string, keyLen int) string {
|
||||||
if len(identity) > keyLen {
|
h := md5.Sum([]byte(seed))
|
||||||
identity = identity[:keyLen]
|
hexStr := hex.EncodeToString(h[:]) // 32 characters
|
||||||
} else if len(identity) < keyLen {
|
if len(hexStr) > keyLen {
|
||||||
|
hexStr = hexStr[:keyLen]
|
||||||
|
} else if len(hexStr) < keyLen {
|
||||||
padded := make([]byte, keyLen)
|
padded := make([]byte, keyLen)
|
||||||
copy(padded, []byte(identity))
|
copy(padded, []byte(hexStr))
|
||||||
identity = string(padded)
|
hexStr = string(padded)
|
||||||
}
|
}
|
||||||
return base64.StdEncoding.EncodeToString([]byte(identity))
|
return base64.StdEncoding.EncodeToString([]byte(hexStr))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ss2022KeyLength returns the required key length for a given SS2022 cipher.
|
// ss2022KeyLength returns the required key length for a given SS2022 cipher.
|
||||||
@@ -618,9 +622,11 @@ func (s *Service) setupNode() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if strings.Contains(method, "2022") {
|
if strings.Contains(method, "2022") {
|
||||||
// SS2022: server_key is used DIRECTLY as PSK (like V2bX)
|
// SS2022 key derivation for panel compatibility
|
||||||
ssOptions.Password = serverKey
|
|
||||||
keyLen := ss2022KeyLength(method)
|
keyLen := ss2022KeyLength(method)
|
||||||
|
ssOptions.Password = ss2022Key(serverKey, keyLen)
|
||||||
|
|
||||||
|
// Create a dummy user (will be replaced by syncUsers)
|
||||||
|
|
||||||
// Create a dummy user (will be replaced by syncUsers)
|
// Create a dummy user (will be replaced by syncUsers)
|
||||||
dummyKey := make([]byte, keyLen)
|
dummyKey := make([]byte, keyLen)
|
||||||
@@ -892,13 +898,12 @@ func (s *Service) syncUsers() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// V2bX/Xboard approach for SS2022 user key:
|
// V2bX/Xboard approach for SS2022 user key:
|
||||||
// Base64 encode the UUID string (clipped/padded to keyLen)
|
|
||||||
if isSS2022 {
|
if isSS2022 {
|
||||||
originalKey := key
|
originalKey := key
|
||||||
key = ss2022UserKey(key, ss2022KeyLen)
|
key = ss2022Key(key, ss2022KeyLen)
|
||||||
if len(newUsers) == 0 {
|
if len(newUsers) == 0 {
|
||||||
// Log first user's key derivation for debugging
|
// Log first user's key derivation for debugging
|
||||||
s.logger.Info("SS2022 user key derivation: ID[:", ss2022KeyLen, "]=", originalKey[:min(ss2022KeyLen, len(originalKey))], " → b64_uPSK=", key)
|
s.logger.Info("SS2022 user key derivation: ID[:", ss2022KeyLen, "]=", originalKey, " → b64_PSK=", key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user