mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2025-12-20 17:10:08 +08:00
chore: sync vless encryption code
This commit is contained in:
parent
e54ca7ceca
commit
d11f9c895c
@ -639,7 +639,7 @@ proxies: # socks5
|
|||||||
uuid: uuid
|
uuid: uuid
|
||||||
network: tcp
|
network: tcp
|
||||||
encryption: "8min-vless-mlkem768client-bas64RawURLEncoding" # 复用八分钟后协商新的 sharedKey,需小于服务端的值
|
encryption: "8min-vless-mlkem768client-bas64RawURLEncoding" # 复用八分钟后协商新的 sharedKey,需小于服务端的值
|
||||||
# encryption: "8min-aes128xor-mlkem768client-bas64RawURLEncoding"
|
# encryption: "8min-xored-mlkem768client-bas64RawURLEncoding"
|
||||||
tls: false #可以不开启tls
|
tls: false #可以不开启tls
|
||||||
udp: true
|
udp: true
|
||||||
|
|
||||||
@ -1348,7 +1348,7 @@ listeners:
|
|||||||
# ws-path: "/" # 如果不为空则开启 websocket 传输层
|
# ws-path: "/" # 如果不为空则开启 websocket 传输层
|
||||||
# grpc-service-name: "GunService" # 如果不为空则开启 grpc 传输层
|
# grpc-service-name: "GunService" # 如果不为空则开启 grpc 传输层
|
||||||
# decryption: "10min-vless-mlkem768seed-bas64RawURLEncoding" # 同时允许 1-RTT 模式与十分钟复用的 0-RTT 模式, 后面base64字符串可由可由 mihomo generate vless-mlkem768 命令生成
|
# decryption: "10min-vless-mlkem768seed-bas64RawURLEncoding" # 同时允许 1-RTT 模式与十分钟复用的 0-RTT 模式, 后面base64字符串可由可由 mihomo generate vless-mlkem768 命令生成
|
||||||
# decryption: "10min-aes128xor-mlkem768seed-bas64RawURLEncoding"
|
# decryption: "10min-xored-mlkem768seed-bas64RawURLEncoding"
|
||||||
# 下面两项如果填写则开启 tls(需要同时填写)
|
# 下面两项如果填写则开启 tls(需要同时填写)
|
||||||
# certificate: ./server.crt
|
# certificate: ./server.crt
|
||||||
# private-key: ./server.key
|
# private-key: ./server.key
|
||||||
|
|||||||
@ -103,12 +103,12 @@ func TestInboundVless_Encryption(t *testing.T) {
|
|||||||
}
|
}
|
||||||
testInboundVless(t, inboundOptions, outboundOptions)
|
testInboundVless(t, inboundOptions, outboundOptions)
|
||||||
})
|
})
|
||||||
t.Run("-aes128xor-", func(t *testing.T) {
|
t.Run("-xored-", func(t *testing.T) {
|
||||||
inboundOptions := inbound.VlessOption{
|
inboundOptions := inbound.VlessOption{
|
||||||
Decryption: "10min-aes128xor-mlkem768seed-" + seedBase64,
|
Decryption: "10min-xored-mlkem768seed-" + seedBase64,
|
||||||
}
|
}
|
||||||
outboundOptions := outbound.VlessOption{
|
outboundOptions := outbound.VlessOption{
|
||||||
Encryption: "8min-aes128xor-mlkem768client-" + clientBase64,
|
Encryption: "8min-xored-mlkem768client-" + clientBase64,
|
||||||
}
|
}
|
||||||
testInboundVless(t, inboundOptions, outboundOptions)
|
testInboundVless(t, inboundOptions, outboundOptions)
|
||||||
})
|
})
|
||||||
|
|||||||
@ -6,4 +6,5 @@
|
|||||||
// https://github.com/XTLS/Xray-core/commit/5c611420487a92f931faefc01d4bf03869f477f6
|
// https://github.com/XTLS/Xray-core/commit/5c611420487a92f931faefc01d4bf03869f477f6
|
||||||
// https://github.com/XTLS/Xray-core/commit/23d7aad461d232bc5bed52dd6aaa731ecd88ad35
|
// https://github.com/XTLS/Xray-core/commit/23d7aad461d232bc5bed52dd6aaa731ecd88ad35
|
||||||
// https://github.com/XTLS/Xray-core/commit/3c20bddfcfd8999be5f9a2ac180dc959950e4c61
|
// https://github.com/XTLS/Xray-core/commit/3c20bddfcfd8999be5f9a2ac180dc959950e4c61
|
||||||
|
// https://github.com/XTLS/Xray-core/commit/1720be168fa069332c418503d30341fc6e01df7f
|
||||||
package encryption
|
package encryption
|
||||||
|
|||||||
@ -31,7 +31,7 @@ func NewClient(encryption string) (*ClientInstance, error) {
|
|||||||
var xor uint32
|
var xor uint32
|
||||||
switch s[1] {
|
switch s[1] {
|
||||||
case "vless":
|
case "vless":
|
||||||
case "aes128xor":
|
case "xored":
|
||||||
xor = 1
|
xor = 1
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("invaild vless encryption value: %s", encryption)
|
return nil, fmt.Errorf("invaild vless encryption value: %s", encryption)
|
||||||
@ -76,7 +76,7 @@ func NewServer(decryption string) (*ServerInstance, error) {
|
|||||||
var xor uint32
|
var xor uint32
|
||||||
switch s[1] {
|
switch s[1] {
|
||||||
case "vless":
|
case "vless":
|
||||||
case "aes128xor":
|
case "xored":
|
||||||
xor = 1
|
xor = 1
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("invaild vless decryption value: %s", decryption)
|
return nil, fmt.Errorf("invaild vless decryption value: %s", decryption)
|
||||||
|
|||||||
@ -10,16 +10,19 @@ import (
|
|||||||
|
|
||||||
type XorConn struct {
|
type XorConn struct {
|
||||||
net.Conn
|
net.Conn
|
||||||
key []byte
|
key []byte
|
||||||
ctr cipher.Stream
|
ctr cipher.Stream
|
||||||
peerCtr cipher.Stream
|
peerCtr cipher.Stream
|
||||||
|
isHeader bool
|
||||||
|
skipNext bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewXorConn(conn net.Conn, key []byte) *XorConn {
|
func NewXorConn(conn net.Conn, key []byte) *XorConn {
|
||||||
return &XorConn{Conn: conn, key: key[:16]}
|
return &XorConn{Conn: conn, key: key[:16]}
|
||||||
|
//chacha20.NewUnauthenticatedCipher()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *XorConn) Write(b []byte) (int, error) {
|
func (c *XorConn) Write(b []byte) (int, error) { // two records at most
|
||||||
if len(b) == 0 {
|
if len(b) == 0 {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
@ -30,7 +33,13 @@ func (c *XorConn) Write(b []byte) (int, error) {
|
|||||||
rand.Read(iv)
|
rand.Read(iv)
|
||||||
c.ctr = cipher.NewCTR(block, iv)
|
c.ctr = cipher.NewCTR(block, iv)
|
||||||
}
|
}
|
||||||
c.ctr.XORKeyStream(b, b) // caller MUST discard b
|
t, l, _ := DecodeHeader(b)
|
||||||
|
if t != 23 {
|
||||||
|
l += 10 // 5+l+5
|
||||||
|
} else {
|
||||||
|
l = 5
|
||||||
|
}
|
||||||
|
c.ctr.XORKeyStream(b[:l], b[:l]) // caller MUST discard b
|
||||||
if iv != nil {
|
if iv != nil {
|
||||||
b = append(iv, b...)
|
b = append(iv, b...)
|
||||||
}
|
}
|
||||||
@ -43,7 +52,7 @@ func (c *XorConn) Write(b []byte) (int, error) {
|
|||||||
return len(b), nil
|
return len(b), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *XorConn) Read(b []byte) (int, error) {
|
func (c *XorConn) Read(b []byte) (int, error) { // 5-bytes, data, 5-bytes...
|
||||||
if len(b) == 0 {
|
if len(b) == 0 {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
@ -54,10 +63,24 @@ func (c *XorConn) Read(b []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
block, _ := aes.NewCipher(c.key)
|
block, _ := aes.NewCipher(c.key)
|
||||||
c.peerCtr = cipher.NewCTR(block, peerIv)
|
c.peerCtr = cipher.NewCTR(block, peerIv)
|
||||||
|
c.isHeader = true
|
||||||
}
|
}
|
||||||
n, err := c.Conn.Read(b)
|
if _, err := io.ReadFull(c.Conn, b); err != nil {
|
||||||
if n > 0 {
|
return 0, err
|
||||||
c.peerCtr.XORKeyStream(b[:n], b[:n])
|
|
||||||
}
|
}
|
||||||
return n, err
|
if c.skipNext {
|
||||||
|
c.skipNext = false
|
||||||
|
return len(b), nil
|
||||||
|
}
|
||||||
|
c.peerCtr.XORKeyStream(b, b)
|
||||||
|
if c.isHeader {
|
||||||
|
if t, _, _ := DecodeHeader(b); t == 23 { // always 5-bytes
|
||||||
|
c.skipNext = true
|
||||||
|
} else {
|
||||||
|
c.isHeader = false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
c.isHeader = true
|
||||||
|
}
|
||||||
|
return len(b), nil
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user