diff --git a/service/xboard/service.go b/service/xboard/service.go index 4a4e90ea..057e7968 100644 --- a/service/xboard/service.go +++ b/service/xboard/service.go @@ -3,6 +3,7 @@ package xboard import ( "bytes" "context" + "crypto/md5" "encoding/base64" "encoding/json" "fmt" @@ -33,19 +34,17 @@ func fixSSKey(key string, length int) string { return key } - // Legacy repetition/truncation logic for raw string keys (common in Xboard/V2board) - password := key - if len(password) > length { - password = password[:length] - } - for len(password) < length { - password += password - } - // Re-truncate after repetition - password = password[:length] + // Xboard style for Shadowsocks 2022: Base64(MD5_Hex(password)) + // 32 hex characters happen to be exactly 32 bytes of ASCII, perfect for aes-256-gcm + hash := md5.Sum([]byte(key)) + hexHash := fmt.Sprintf("%x", hash) - // Convert to Base64 so sing-box treats it as a raw byte key - return base64.StdEncoding.EncodeToString([]byte(password)) + // For 128-bit methods, truncate the hex string to 16 + if length == 16 && len(hexHash) > 16 { + hexHash = hexHash[:16] + } + + return base64.StdEncoding.EncodeToString([]byte(hexHash)) } func RegisterService(registry *boxService.Registry) {