header.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. package vmess
  2. import (
  3. "bytes"
  4. "crypto/aes"
  5. "crypto/cipher"
  6. "crypto/hmac"
  7. "crypto/rand"
  8. "crypto/sha256"
  9. "encoding/binary"
  10. "hash"
  11. "hash/crc32"
  12. "time"
  13. )
  14. const (
  15. kdfSaltConstAuthIDEncryptionKey = "AES Auth ID Encryption"
  16. kdfSaltConstAEADRespHeaderLenKey = "AEAD Resp Header Len Key"
  17. kdfSaltConstAEADRespHeaderLenIV = "AEAD Resp Header Len IV"
  18. kdfSaltConstAEADRespHeaderPayloadKey = "AEAD Resp Header Key"
  19. kdfSaltConstAEADRespHeaderPayloadIV = "AEAD Resp Header IV"
  20. kdfSaltConstVMessAEADKDF = "VMess AEAD KDF"
  21. kdfSaltConstVMessHeaderPayloadAEADKey = "VMess Header AEAD Key"
  22. kdfSaltConstVMessHeaderPayloadAEADIV = "VMess Header AEAD Nonce"
  23. kdfSaltConstVMessHeaderPayloadLengthAEADKey = "VMess Header AEAD Key_Length"
  24. kdfSaltConstVMessHeaderPayloadLengthAEADIV = "VMess Header AEAD Nonce_Length"
  25. )
  26. func kdf(key []byte, path ...string) []byte {
  27. hmacCreator := &hMacCreator{value: []byte(kdfSaltConstVMessAEADKDF)}
  28. for _, v := range path {
  29. hmacCreator = &hMacCreator{value: []byte(v), parent: hmacCreator}
  30. }
  31. hmacf := hmacCreator.Create()
  32. hmacf.Write(key)
  33. return hmacf.Sum(nil)
  34. }
  35. type hMacCreator struct {
  36. parent *hMacCreator
  37. value []byte
  38. }
  39. func (h *hMacCreator) Create() hash.Hash {
  40. if h.parent == nil {
  41. return hmac.New(sha256.New, h.value)
  42. }
  43. return hmac.New(h.parent.Create, h.value)
  44. }
  45. func createAuthID(cmdKey []byte, time int64) [16]byte {
  46. buf := &bytes.Buffer{}
  47. binary.Write(buf, binary.BigEndian, time)
  48. random := make([]byte, 4)
  49. rand.Read(random)
  50. buf.Write(random)
  51. zero := crc32.ChecksumIEEE(buf.Bytes())
  52. binary.Write(buf, binary.BigEndian, zero)
  53. aesBlock, _ := aes.NewCipher(kdf(cmdKey[:], kdfSaltConstAuthIDEncryptionKey)[:16])
  54. var result [16]byte
  55. aesBlock.Encrypt(result[:], buf.Bytes())
  56. return result
  57. }
  58. func sealVMessAEADHeader(key [16]byte, data []byte, t time.Time) []byte {
  59. generatedAuthID := createAuthID(key[:], t.Unix())
  60. connectionNonce := make([]byte, 8)
  61. rand.Read(connectionNonce)
  62. aeadPayloadLengthSerializedByte := make([]byte, 2)
  63. binary.BigEndian.PutUint16(aeadPayloadLengthSerializedByte, uint16(len(data)))
  64. var payloadHeaderLengthAEADEncrypted []byte
  65. {
  66. payloadHeaderLengthAEADKey := kdf(key[:], kdfSaltConstVMessHeaderPayloadLengthAEADKey, string(generatedAuthID[:]), string(connectionNonce))[:16]
  67. payloadHeaderLengthAEADNonce := kdf(key[:], kdfSaltConstVMessHeaderPayloadLengthAEADIV, string(generatedAuthID[:]), string(connectionNonce))[:12]
  68. payloadHeaderLengthAEADAESBlock, _ := aes.NewCipher(payloadHeaderLengthAEADKey)
  69. payloadHeaderAEAD, _ := cipher.NewGCM(payloadHeaderLengthAEADAESBlock)
  70. payloadHeaderLengthAEADEncrypted = payloadHeaderAEAD.Seal(nil, payloadHeaderLengthAEADNonce, aeadPayloadLengthSerializedByte, generatedAuthID[:])
  71. }
  72. var payloadHeaderAEADEncrypted []byte
  73. {
  74. payloadHeaderAEADKey := kdf(key[:], kdfSaltConstVMessHeaderPayloadAEADKey, string(generatedAuthID[:]), string(connectionNonce))[:16]
  75. payloadHeaderAEADNonce := kdf(key[:], kdfSaltConstVMessHeaderPayloadAEADIV, string(generatedAuthID[:]), string(connectionNonce))[:12]
  76. payloadHeaderAEADAESBlock, _ := aes.NewCipher(payloadHeaderAEADKey)
  77. payloadHeaderAEAD, _ := cipher.NewGCM(payloadHeaderAEADAESBlock)
  78. payloadHeaderAEADEncrypted = payloadHeaderAEAD.Seal(nil, payloadHeaderAEADNonce, data, generatedAuthID[:])
  79. }
  80. outputBuffer := &bytes.Buffer{}
  81. outputBuffer.Write(generatedAuthID[:])
  82. outputBuffer.Write(payloadHeaderLengthAEADEncrypted)
  83. outputBuffer.Write(connectionNonce)
  84. outputBuffer.Write(payloadHeaderAEADEncrypted)
  85. return outputBuffer.Bytes()
  86. }