Browse Source

Commands: Add `vlessenc` (generate complete json pair directly) (#5078)

https://github.com/XTLS/Xray-core/pull/5078#issuecomment-3254161589

---------

Co-authored-by: RPRX <[email protected]>
风扇滑翔翼 3 months ago
parent
commit
8b579bf3ec

+ 1 - 0
main/commands/all/commands.go

@@ -18,5 +18,6 @@ func init() {
 		cmdWG,
 		cmdMLDSA65,
 		cmdMLKEM768,
+		cmdVLESSEnc,
 	)
 }

+ 19 - 7
main/commands/all/curve25519.go

@@ -25,6 +25,21 @@ func Curve25519Genkey(StdEncoding bool, input_base64 string) {
 			return
 		}
 	}
+	privateKey, password, hash32, err := genCurve25519(privateKey)
+	if err != nil {
+		fmt.Println(err)
+		return
+	}
+	fmt.Printf("PrivateKey: %v\nPassword: %v\nHash32: %v\n",
+		encoding.EncodeToString(privateKey),
+		encoding.EncodeToString(password),
+		encoding.EncodeToString(hash32[:]))
+}
+
+func genCurve25519(inputPrivateKey []byte) (privateKey []byte, password []byte, hash32 [32]byte, returnErr error) {
+	if len(inputPrivateKey) > 0 {
+		privateKey = inputPrivateKey
+	}
 	if privateKey == nil {
 		privateKey = make([]byte, 32)
 		rand.Read(privateKey)
@@ -39,13 +54,10 @@ func Curve25519Genkey(StdEncoding bool, input_base64 string) {
 
 	key, err := ecdh.X25519().NewPrivateKey(privateKey)
 	if err != nil {
-		fmt.Println(err.Error())
+		returnErr = err
 		return
 	}
-	password := key.PublicKey().Bytes()
-	hash32 := blake3.Sum256(password)
-	fmt.Printf("PrivateKey: %v\nPassword: %v\nHash32: %v",
-		encoding.EncodeToString(privateKey),
-		encoding.EncodeToString(password),
-		encoding.EncodeToString(hash32[:]))
+	password = key.PublicKey().Bytes()
+	hash32 = blake3.Sum256(password)
+	return
 }

+ 1 - 1
main/commands/all/mldsa65.go

@@ -40,7 +40,7 @@ func executeMLDSA65(cmd *base.Command, args []string) {
 		rand.Read(seed[:])
 	}
 	pub, _ := mldsa65.NewKeyFromSeed(&seed)
-	fmt.Printf("Seed: %v\nVerify: %v",
+	fmt.Printf("Seed: %v\nVerify: %v\n",
 		base64.RawURLEncoding.EncodeToString(seed[:]),
 		base64.RawURLEncoding.EncodeToString(pub.Bytes()))
 }

+ 16 - 6
main/commands/all/mlkem768.go

@@ -12,9 +12,9 @@ import (
 
 var cmdMLKEM768 = &base.Command{
 	UsageLine: `{{.Exec}} mlkem768 [-i "seed (base64.RawURLEncoding)"]`,
-	Short:     `Generate key pair for ML-KEM-768 post-quantum key exchange (VLESS)`,
+	Short:     `Generate key pair for ML-KEM-768 post-quantum key exchange (VLESS Encryption)`,
 	Long: `
-Generate key pair for ML-KEM-768 post-quantum key exchange (VLESS).
+Generate key pair for ML-KEM-768 post-quantum key exchange (VLESS Encryption).
 
 Random: {{.Exec}} mlkem768
 
@@ -40,11 +40,21 @@ func executeMLKEM768(cmd *base.Command, args []string) {
 	} else {
 		rand.Read(seed[:])
 	}
-	key, _ := mlkem.NewDecapsulationKey768(seed[:])
-	client := key.EncapsulationKey().Bytes()
-	hash32 := blake3.Sum256(client)
-	fmt.Printf("Seed: %v\nClient: %v\nHash32: %v",
+	seed, client, hash32 := genMLKEM768(&seed)
+	fmt.Printf("Seed: %v\nClient: %v\nHash32: %v\n",
 		base64.RawURLEncoding.EncodeToString(seed[:]),
 		base64.RawURLEncoding.EncodeToString(client),
 		base64.RawURLEncoding.EncodeToString(hash32[:]))
 }
+
+func genMLKEM768(inputSeed *[64]byte) (seed [64]byte, client []byte, hash32 [32]byte) {
+	if inputSeed == nil {
+		rand.Read(seed[:])
+	} else {
+		seed = *inputSeed
+	}
+	key, _ := mlkem.NewDecapsulationKey768(seed[:])
+	client = key.EncapsulationKey().Bytes()
+	hash32 = blake3.Sum256(client)
+	return
+}

+ 41 - 0
main/commands/all/vlessenc.go

@@ -0,0 +1,41 @@
+package all
+
+import (
+	"encoding/base64"
+	"fmt"
+	"strings"
+
+	"github.com/xtls/xray-core/main/commands/base"
+)
+
+var cmdVLESSEnc = &base.Command{
+	UsageLine: `{{.Exec}} vlessenc`,
+	Short:     `Generate decryption/encryption json pair (VLESS Encryption)`,
+	Long: `
+Generate decryption/encryption json pair (VLESS Encryption).
+`,
+}
+
+func init() {
+	cmdVLESSEnc.Run = executeVLESSEnc // break init loop
+}
+
+func executeVLESSEnc(cmd *base.Command, args []string) {
+	privateKey, password, _, _ := genCurve25519(nil)
+	serverKey := base64.RawURLEncoding.EncodeToString(privateKey)
+	clientKey := base64.RawURLEncoding.EncodeToString(password)
+	decryption := generateDotConfig("mlkem768x25519plus", "native", "600s", serverKey)
+	encryption := generateDotConfig("mlkem768x25519plus", "native", "0rtt", clientKey)
+	seed, client, _ := genMLKEM768(nil)
+	serverKeyPQ := base64.RawURLEncoding.EncodeToString(seed[:])
+	clientKeyPQ := base64.RawURLEncoding.EncodeToString(client)
+	decryptionPQ := generateDotConfig("mlkem768x25519plus", "native", "600s", serverKeyPQ)
+	encryptionPQ := generateDotConfig("mlkem768x25519plus", "native", "0rtt", clientKeyPQ)
+	fmt.Printf("Choose one Authentication to use, do not mix them. Ephemeral key exchange is Post-Quantum safe anyway.\n\n")
+	fmt.Printf("Authentication: X25519, not Post-Quantum\n\"decryption\": \"%v\"\n\"encryption\": \"%v\"\n\n", decryption, encryption)
+	fmt.Printf("Authentication: ML-KEM-768, Post-Quantum\n\"decryption\": \"%v\"\n\"encryption\": \"%v\"\n", decryptionPQ, encryptionPQ)
+}
+
+func generateDotConfig(fields ...string) string {
+	return strings.Join(fields, ".")
+}

+ 2 - 2
main/commands/all/x25519.go

@@ -6,9 +6,9 @@ import (
 
 var cmdX25519 = &base.Command{
 	UsageLine: `{{.Exec}} x25519 [-i "private key (base64.RawURLEncoding)"] [--std-encoding]`,
-	Short:     `Generate key pair for X25519 key exchange (VLESS, REALITY)`,
+	Short:     `Generate key pair for X25519 key exchange (REALITY, VLESS Encryption)`,
 	Long: `
-Generate key pair for X25519 key exchange (VLESS, REALITY).
+Generate key pair for X25519 key exchange (REALITY, VLESS Encryption).
 
 Random: {{.Exec}} x25519