github.com/Asutorufa/yuhaiin@v0.3.6-0.20240502055049-7984da7023a0/pkg/net/proxy/vmess/user.go (about) 1 package vmess 2 3 import ( 4 "crypto/md5" 5 "encoding/binary" 6 "time" 7 8 "github.com/Asutorufa/yuhaiin/pkg/utils/uuid" 9 ) 10 11 // User of vmess client 12 type User struct { 13 UUID uuid.UUID 14 CmdKey [16]byte 15 } 16 17 // NewUser . 18 func NewUser(uuid uuid.UUID) *User { 19 u := &User{UUID: uuid} 20 copy(u.CmdKey[:], GetKey(uuid)) 21 return u 22 } 23 24 func nextID(oldID uuid.UUID) (newID uuid.UUID) { 25 md5hash := md5.New() 26 md5hash.Write(oldID.Bytes()) 27 md5hash.Write([]byte("16167dc8-16b6-4e6d-b8bb-65dd68113a81")) 28 var buf [16]byte 29 for { 30 md5hash.Sum(buf[:0]) 31 if newId := uuid.FromStd(buf[:]); newId.IsValid() && newId != oldID { 32 return newId 33 } 34 md5hash.Write([]byte("533eff8a-4113-4b10-b5ce-0f5d76b98cd2")) 35 } 36 } 37 38 // GenAlterIDUsers generates users according to primary user's id and alterID 39 func (u *User) GenAlterIDUsers(alterID int) []*User { 40 users := make([]*User, alterID) 41 preID := u.UUID 42 for i := 0; i < alterID; i++ { 43 newID := nextID(preID) 44 // NOTE: alterID user is a user which have a different uuid but a same cmdkey with the primary user. 45 users[i] = &User{UUID: newID, CmdKey: u.CmdKey} 46 preID = newID 47 } 48 49 return users 50 } 51 52 // GetKey returns the key of AES-128-CFB encrypter 53 // Key:MD5(UUID + []byte('c48619fe-8f02-49e0-b9e9-edf763e17e21')) 54 func GetKey(uuid uuid.UUID) []byte { 55 md5hash := md5.New() 56 md5hash.Write(uuid.Bytes()) 57 md5hash.Write([]byte("c48619fe-8f02-49e0-b9e9-edf763e17e21")) 58 return md5hash.Sum(nil) 59 } 60 61 // TimestampHash returns the iv of AES-128-CFB encrypter 62 // IV:MD5(X + X + X + X),X = []byte(timestamp.now) (8 bytes, Big Endian) 63 func TimestampHash(t time.Time) []byte { 64 md5hash := md5.New() 65 66 ts := make([]byte, 8) 67 binary.BigEndian.PutUint64(ts, uint64(t.Unix())) 68 md5hash.Write(ts) 69 md5hash.Write(ts) 70 md5hash.Write(ts) 71 md5hash.Write(ts) 72 return md5hash.Sum(nil) 73 }