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  }