forked from p4gefau1t/trojan-go
-
Notifications
You must be signed in to change notification settings - Fork 1
/
user.go
83 lines (73 loc) · 1.91 KB
/
user.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package vmess
import (
"bytes"
"crypto/md5"
"encoding/binary"
"encoding/hex"
"errors"
"strings"
)
// Vmess user
type User struct {
UUID [16]byte
CmdKey [16]byte
}
func NewUser(uuid [16]byte) *User {
u := &User{UUID: uuid}
copy(u.CmdKey[:], GetKey(uuid))
return u
}
func nextID(oldID [16]byte) (newID [16]byte) {
md5hash := md5.New()
md5hash.Write(oldID[:])
md5hash.Write([]byte("16167dc8-16b6-4e6d-b8bb-65dd68113a81"))
for {
md5hash.Sum(newID[:0])
if !bytes.Equal(oldID[:], newID[:]) {
return
}
md5hash.Write([]byte("533eff8a-4113-4b10-b5ce-0f5d76b98cd2"))
}
}
// GenAlterIDUsers generates users according to primary user's id and alterID
func (u *User) GenAlterIDUsers(alterID int) []*User {
users := make([]*User, alterID)
preID := u.UUID
for i := 0; i < alterID; i++ {
newID := nextID(preID)
// NOTE: alterID user is a user which have a different uuid but a same cmdkey with the primary user.
users[i] = &User{UUID: newID, CmdKey: u.CmdKey}
preID = newID
}
return users
}
// StrToUUID converts string to uuid
func StrToUUID(s string) (uuid [16]byte, err error) {
b := []byte(strings.Replace(s, "-", "", -1))
if len(b) != 32 {
return uuid, errors.New("invalid UUID: " + s)
}
_, err = hex.Decode(uuid[:], b)
return
}
// GetKey returns the key of AES-128-CFB encrypter
// Key:MD5(UUID + []byte('c48619fe-8f02-49e0-b9e9-edf763e17e21'))
func GetKey(uuid [16]byte) []byte {
md5hash := md5.New()
md5hash.Write(uuid[:])
md5hash.Write([]byte("c48619fe-8f02-49e0-b9e9-edf763e17e21"))
return md5hash.Sum(nil)
}
// TimestampHash returns the iv of AES-128-CFB encrypter
// IV:MD5(X + X + X + X),X = []byte(timestamp.now) (8 bytes, Big Endian)
func TimestampHash(unixSec int64) []byte {
ts := GetBuffer(8)
defer PutBuffer(ts)
binary.BigEndian.PutUint64(ts, uint64(unixSec))
md5hash := md5.New()
md5hash.Write(ts)
md5hash.Write(ts)
md5hash.Write(ts)
md5hash.Write(ts)
return md5hash.Sum(nil)
}