tlsfinger

package module
v0.0.0-...-efa819b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 28, 2026 License: BSD-3-Clause Imports: 10 Imported by: 1

README

TLS Finger

This repository is an fingeprint extension of the gitlab.com/go-extension/tls

Currently implements fingerprint

  • Google Chrome:
    • AES: 102, 106
  • Microsoft Edge:
    • AES: 106, 122, 140
  • Mozilla Firefox:
    • AES: 144
  • Apple Safari: 18.7

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	Finger_Chrome         = Finger_Chrome_106
	Finger_Edge           = Finger_Edge_140
	Finger_Edge_Websocket = Finger_Edge_140_Websocket
	Finger_Firefox        = Finger_Firefox_144
	Finger_Safari         = Finger_Safari_18_7
)
View Source
var Finger_Chrome_102 = Finger{
	JA3: "772,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-21,29-23-24,0",
	Config: &tls.Config{
		Behavior: &tls.Behavior{
			CheckUselessRecordsCount: func(count tls.UselessRecordCount) bool {
				return !(count.ChangeCipherSpec > 32 || count.WarningAlerts > 32 || count.WarningAlerts > 5)
			},
			ChangeCipherSpec: tls.ChangeCipherSpecBehavior{
				DecodeResponse:                alertIllegalParameter,
				DecodeResponseTLS13:           alertBadRecordMAC,
				RejectPlaintextAfterEncrypted: true,
				RejectAfterEncrypted:          true,
			},
			Alert: tls.AlertBehavior{
				DecodeResponse:  alertDecodeError,
				UnknownResponse: alertIllegalParameter,
				LevelCheck:      true,
			},
		},
		CipherSuites: []uint16{
			tls.GREASE_PLACEHOLDER,
			tls.TLS_AES_128_GCM_SHA256,
			tls.TLS_AES_256_GCM_SHA384,
			tls.TLS_CHACHA20_POLY1305_SHA256,
			tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
			tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
			tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
			tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
			tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_RSA_WITH_AES_128_CBC_SHA,
			tls.TLS_RSA_WITH_AES_256_CBC_SHA,
		},
		PreferCipherSuites: true,
		Renegotiation:      tls.RenegotiateOnceAsClient,
		CurvePreferences: []tls.CurveID{
			tls.GREASE_PLACEHOLDER,
			tls.X25519,
			tls.CurveP256,
			tls.CurveP384,
		},
		KeySharePreferences: []tls.CurveID{
			tls.GREASE_PLACEHOLDER,
			tls.X25519,
		},
		MinVersion: tls.VersionTLS12,
		MaxVersion: tls.VersionTLS13,
		SupportedVersions: []uint16{
			tls.GREASE_PLACEHOLDER,
			tls.VersionTLS13,
			tls.VersionTLS12,
		},
		CertificateCompressionPreferences: []tls.CertificateCompressionAlgorithm{
			tls.Brotli,
		},
		SignatureAlgorithmsPreferences: []tls.SignatureScheme{
			tls.ECDSAWithP256AndSHA256,
			tls.PSSWithSHA256,
			tls.PKCS1WithSHA256,
			tls.ECDSAWithP384AndSHA384,
			tls.PSSWithSHA384,
			tls.PKCS1WithSHA384,
			tls.PSSWithSHA512,
			tls.PKCS1WithSHA512,
		},
		NextProtos:        []string{"h2", "http/1.1"},
		NextProtoSettings: map[string][]byte{"h2": nil},
		ClientHelloPadding: func(pq tls.PaddingRequest) (uint16, bool) {
			if pq.HelloInner || pq.HelloRetryRequest || pq.QUIC {
				return 0, false
			}

			if pq.UnpaddedLength > 0xff && pq.UnpaddedLength < 0x200 {
				paddingLen := 0x200 - pq.UnpaddedLength
				if paddingLen >= 4+1 {
					paddingLen -= 4
				} else {
					paddingLen = 1
				}
				return uint16(paddingLen), true
			}

			return 0, false
		},
		Extensions: []tls.Extension{
			&tls.GREASEExtension{},
			&tls.ServerNameIndicationExtension{},
			&tls.ExtendedMasterSecretExtension{},
			&tls.RenegotiationInfoExtension{},
			&tls.SupportedGroupsExtension{},
			&tls.SupportedPointsExtension{},
			&tls.SessionTicketExtension{},
			&tls.ALPNExtension{},
			&tls.StatusRequestExtension{},
			&tls.SignatureAlgorithmsExtension{},
			&tls.SCTExtension{},
			&tls.KeyShareExtension{},
			&tls.PSKModesExtension{},
			&tls.SupportedVersionsExtension{},
			&tls.CompressedCertificateExtension{},
			&tls.LegacyALPSExtension{},
			&tls.GREASEExtension{},
			&tls.PaddingExtension{},
			&tls.PreSharedKeyExtension{},
		},
		EncryptedClientHelloConfig: &tls.ECHConfig{
			Disabled: true,
		},
		ClientSessionCache: emptyCache,
	},
}
View Source
var Finger_Chrome_106 = Finger{
	JA3: "772,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-21,29-23-24,0",
	Config: &tls.Config{
		Behavior: &tls.Behavior{
			CheckUselessRecordsCount: func(count tls.UselessRecordCount) bool {
				return !(count.ChangeCipherSpec > 32 || count.WarningAlerts > 32 || count.WarningAlerts > 5)
			},
			ChangeCipherSpec: tls.ChangeCipherSpecBehavior{
				DecodeResponse:                alertIllegalParameter,
				DecodeResponseTLS13:           alertBadRecordMAC,
				RejectPlaintextAfterEncrypted: true,
				RejectAfterEncrypted:          true,
			},
			Alert: tls.AlertBehavior{
				DecodeResponse:  alertDecodeError,
				UnknownResponse: alertIllegalParameter,
				LevelCheck:      true,
			},
		},
		CipherSuites: []uint16{
			tls.GREASE_PLACEHOLDER,
			tls.TLS_AES_128_GCM_SHA256,
			tls.TLS_AES_256_GCM_SHA384,
			tls.TLS_CHACHA20_POLY1305_SHA256,
			tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
			tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
			tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
			tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
			tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_RSA_WITH_AES_128_CBC_SHA,
			tls.TLS_RSA_WITH_AES_256_CBC_SHA,
		},
		PreferCipherSuites: true,
		Renegotiation:      tls.RenegotiateOnceAsClient,
		CurvePreferences: []tls.CurveID{
			tls.GREASE_PLACEHOLDER,
			tls.X25519,
			tls.CurveP256,
			tls.CurveP384,
		},
		KeySharePreferences: []tls.CurveID{
			tls.GREASE_PLACEHOLDER,
			tls.X25519,
		},
		MinVersion: tls.VersionTLS12,
		MaxVersion: tls.VersionTLS13,
		SupportedVersions: []uint16{
			tls.GREASE_PLACEHOLDER,
			tls.VersionTLS13,
			tls.VersionTLS12,
		},
		CertificateCompressionPreferences: []tls.CertificateCompressionAlgorithm{
			tls.Brotli,
		},
		SignatureAlgorithmsPreferences: []tls.SignatureScheme{
			tls.ECDSAWithP256AndSHA256,
			tls.PSSWithSHA256,
			tls.PKCS1WithSHA256,
			tls.ECDSAWithP384AndSHA384,
			tls.PSSWithSHA384,
			tls.PKCS1WithSHA384,
			tls.PSSWithSHA512,
			tls.PKCS1WithSHA512,
		},
		NextProtos:        []string{"h2", "http/1.1"},
		NextProtoSettings: map[string][]byte{"h2": nil},
		ClientHelloPadding: func(pq tls.PaddingRequest) (uint16, bool) {
			if pq.HelloInner || pq.HelloRetryRequest || pq.QUIC {
				return 0, false
			}

			if pq.UnpaddedLength > 0xff && pq.UnpaddedLength < 0x200 {
				paddingLen := 0x200 - pq.UnpaddedLength
				if paddingLen >= 4+1 {
					paddingLen -= 4
				} else {
					paddingLen = 1
				}
				return uint16(paddingLen), true
			}

			return 0, false
		},
		ShuffleExtensions: true,
		Extensions: []tls.Extension{
			&tls.GREASEExtension{},
			&tls.ServerNameIndicationExtension{},
			&tls.ExtendedMasterSecretExtension{},
			&tls.RenegotiationInfoExtension{},
			&tls.SupportedGroupsExtension{},
			&tls.SupportedPointsExtension{},
			&tls.SessionTicketExtension{},
			&tls.ALPNExtension{},
			&tls.StatusRequestExtension{},
			&tls.SignatureAlgorithmsExtension{},
			&tls.SCTExtension{},
			&tls.KeyShareExtension{},
			&tls.PSKModesExtension{},
			&tls.SupportedVersionsExtension{},
			&tls.CompressedCertificateExtension{},
			&tls.LegacyALPSExtension{},
			&tls.GREASEExtension{},
			&tls.PaddingExtension{},
			&tls.PreSharedKeyExtension{},
		},
		EncryptedClientHelloConfig: &tls.ECHConfig{
			Disabled: true,
		},
		ClientSessionCache: emptyCache,
	},
}
View Source
var Finger_Edge_106 = Finger{
	JA3: "772,4865-4866-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-21,29-23-24,0",
	Config: &tls.Config{
		Behavior: &tls.Behavior{
			CheckUselessRecordsCount: func(count tls.UselessRecordCount) bool {
				return !(count.ChangeCipherSpec > 32 || count.WarningAlerts > 32 || count.WarningAlerts > 5)
			},
			ChangeCipherSpec: tls.ChangeCipherSpecBehavior{
				DecodeResponse:                alertIllegalParameter,
				DecodeResponseTLS13:           alertBadRecordMAC,
				RejectPlaintextAfterEncrypted: true,
				RejectAfterEncrypted:          true,
			},
			Alert: tls.AlertBehavior{
				DecodeResponse:  alertDecodeError,
				UnknownResponse: alertIllegalParameter,
				LevelCheck:      true,
			},
		},
		CipherSuites: []uint16{
			tls.GREASE_PLACEHOLDER,
			tls.TLS_AES_128_GCM_SHA256,
			tls.TLS_AES_256_GCM_SHA384,
			tls.TLS_AES_256_GCM_SHA384,
			tls.TLS_CHACHA20_POLY1305_SHA256,
			tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
			tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
			tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
			tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
			tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_RSA_WITH_AES_128_CBC_SHA,
			tls.TLS_RSA_WITH_AES_256_CBC_SHA,
		},
		PreferCipherSuites: true,
		Renegotiation:      tls.RenegotiateOnceAsClient,
		CurvePreferences: []tls.CurveID{
			tls.GREASE_PLACEHOLDER,
			tls.X25519,
			tls.CurveP256,
			tls.CurveP384,
		},
		KeySharePreferences: []tls.CurveID{
			tls.GREASE_PLACEHOLDER,
			tls.X25519,
		},
		MinVersion: tls.VersionTLS12,
		MaxVersion: tls.VersionTLS13,
		SupportedVersions: []uint16{
			tls.GREASE_PLACEHOLDER,
			tls.VersionTLS13,
			tls.VersionTLS12,
		},
		CertificateCompressionPreferences: []tls.CertificateCompressionAlgorithm{
			tls.Brotli,
		},
		SignatureAlgorithmsPreferences: []tls.SignatureScheme{
			tls.ECDSAWithP256AndSHA256,
			tls.PSSWithSHA256,
			tls.PKCS1WithSHA256,
			tls.ECDSAWithP384AndSHA384,
			tls.PSSWithSHA384,
			tls.PKCS1WithSHA384,
			tls.PSSWithSHA512,
			tls.PKCS1WithSHA512,
		},
		NextProtos:        []string{"h2", "http/1.1"},
		NextProtoSettings: map[string][]byte{"h2": nil},
		ClientHelloPadding: func(pq tls.PaddingRequest) (uint16, bool) {
			if pq.HelloInner || pq.HelloRetryRequest || pq.QUIC {
				return 0, false
			}

			if pq.UnpaddedLength > 0xff && pq.UnpaddedLength < 0x200 {
				paddingLen := 0x200 - pq.UnpaddedLength
				if paddingLen >= 4+1 {
					paddingLen -= 4
				} else {
					paddingLen = 1
				}
				return uint16(paddingLen), true
			}

			return 0, false
		},
		Extensions: []tls.Extension{
			&tls.GREASEExtension{},
			&tls.ServerNameIndicationExtension{},
			&tls.ExtendedMasterSecretExtension{},
			&tls.RenegotiationInfoExtension{},
			&tls.SupportedGroupsExtension{},
			&tls.SupportedPointsExtension{},
			&tls.SessionTicketExtension{},
			&tls.ALPNExtension{},
			&tls.StatusRequestExtension{},
			&tls.SignatureAlgorithmsExtension{},
			&tls.SCTExtension{},
			&tls.KeyShareExtension{},
			&tls.PSKModesExtension{},
			&tls.SupportedVersionsExtension{},
			&tls.CompressedCertificateExtension{},
			&tls.LegacyALPSExtension{},
			&tls.GREASEExtension{},
			&tls.PaddingExtension{},
			&tls.PreSharedKeyExtension{},
		},
		EncryptedClientHelloConfig: &tls.ECHConfig{
			Disabled: true,
		},
		ClientSessionCache: emptyCache,
	},
}
View Source
var Finger_Edge_106_Websocket = Finger{
	JA3: "772,4865-4866-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-21,29-23-24,0",
	Config: &tls.Config{
		Behavior: &tls.Behavior{
			CheckUselessRecordsCount: func(count tls.UselessRecordCount) bool {
				return !(count.ChangeCipherSpec > 32 || count.WarningAlerts > 32 || count.WarningAlerts > 5)
			},
			ChangeCipherSpec: tls.ChangeCipherSpecBehavior{
				DecodeResponse:                alertIllegalParameter,
				DecodeResponseTLS13:           alertBadRecordMAC,
				RejectPlaintextAfterEncrypted: true,
				RejectAfterEncrypted:          true,
			},
			Alert: tls.AlertBehavior{
				DecodeResponse:  alertDecodeError,
				UnknownResponse: alertIllegalParameter,
				LevelCheck:      true,
			},
		},
		CipherSuites: []uint16{
			tls.GREASE_PLACEHOLDER,
			tls.TLS_AES_128_GCM_SHA256,
			tls.TLS_AES_256_GCM_SHA384,
			tls.TLS_AES_256_GCM_SHA384,
			tls.TLS_CHACHA20_POLY1305_SHA256,
			tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
			tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
			tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
			tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
			tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_RSA_WITH_AES_128_CBC_SHA,
			tls.TLS_RSA_WITH_AES_256_CBC_SHA,
		},
		PreferCipherSuites: true,
		Renegotiation:      tls.RenegotiateOnceAsClient,
		CurvePreferences: []tls.CurveID{
			tls.GREASE_PLACEHOLDER,
			tls.X25519,
			tls.CurveP256,
			tls.CurveP384,
		},
		KeySharePreferences: []tls.CurveID{
			tls.GREASE_PLACEHOLDER,
			tls.X25519,
		},
		MinVersion: tls.VersionTLS12,
		MaxVersion: tls.VersionTLS13,
		SupportedVersions: []uint16{
			tls.GREASE_PLACEHOLDER,
			tls.VersionTLS13,
			tls.VersionTLS12,
		},
		CertificateCompressionPreferences: []tls.CertificateCompressionAlgorithm{
			tls.Brotli,
		},
		SignatureAlgorithmsPreferences: []tls.SignatureScheme{
			tls.ECDSAWithP256AndSHA256,
			tls.PSSWithSHA256,
			tls.PKCS1WithSHA256,
			tls.ECDSAWithP384AndSHA384,
			tls.PSSWithSHA384,
			tls.PKCS1WithSHA384,
			tls.PSSWithSHA512,
			tls.PKCS1WithSHA512,
		},
		NextProtos:        []string{"http/1.1"},
		NextProtoSettings: map[string][]byte{"h2": nil},
		ClientHelloPadding: func(pq tls.PaddingRequest) (uint16, bool) {
			if pq.HelloInner || pq.HelloRetryRequest || pq.QUIC {
				return 0, false
			}

			if pq.UnpaddedLength > 0xff && pq.UnpaddedLength < 0x200 {
				paddingLen := 0x200 - pq.UnpaddedLength
				if paddingLen >= 4+1 {
					paddingLen -= 4
				} else {
					paddingLen = 1
				}
				return uint16(paddingLen), true
			}

			return 0, false
		},
		Extensions: []tls.Extension{
			&tls.GREASEExtension{},
			&tls.ServerNameIndicationExtension{},
			&tls.ExtendedMasterSecretExtension{},
			&tls.RenegotiationInfoExtension{},
			&tls.SupportedGroupsExtension{},
			&tls.SupportedPointsExtension{},
			&tls.SessionTicketExtension{},
			&tls.ALPNExtension{},
			&tls.StatusRequestExtension{},
			&tls.SignatureAlgorithmsExtension{},
			&tls.SCTExtension{},
			&tls.KeyShareExtension{},
			&tls.PSKModesExtension{},
			&tls.SupportedVersionsExtension{},
			&tls.CompressedCertificateExtension{},
			&tls.LegacyALPSExtension{},
			&tls.GREASEExtension{},
			&tls.PaddingExtension{},
			&tls.PreSharedKeyExtension{},
		},
		EncryptedClientHelloConfig: &tls.ECHConfig{
			Disabled: true,
		},
		ClientSessionCache: emptyCache,
	},
}
View Source
var Finger_Edge_122 = Finger{
	JA3: "772,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,5-10-11-13-16-18-23-27-35-43-45-51-17513-65281-65037-21,29-23-24,0",
	Config: &tls.Config{
		Behavior: &tls.Behavior{
			CheckUselessRecordsCount: func(count tls.UselessRecordCount) bool {
				return !(count.ChangeCipherSpec > 32 || count.WarningAlerts > 32 || count.WarningAlerts > 5)
			},
			ChangeCipherSpec: tls.ChangeCipherSpecBehavior{
				DecodeResponse:                alertIllegalParameter,
				DecodeResponseTLS13:           alertBadRecordMAC,
				RejectPlaintextAfterEncrypted: true,
				RejectAfterEncrypted:          true,
			},
			Alert: tls.AlertBehavior{
				DecodeResponse:  alertDecodeError,
				UnknownResponse: alertIllegalParameter,
				LevelCheck:      true,
			},
		},
		CipherSuites: []uint16{
			tls.GREASE_PLACEHOLDER,
			tls.TLS_AES_128_GCM_SHA256,
			tls.TLS_AES_256_GCM_SHA384,
			tls.TLS_CHACHA20_POLY1305_SHA256,
			tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
			tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
			tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
			tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
			tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_RSA_WITH_AES_128_CBC_SHA,
			tls.TLS_RSA_WITH_AES_256_CBC_SHA,
		},
		PreferCipherSuites: true,
		Renegotiation:      tls.RenegotiateOnceAsClient,
		CurvePreferences: []tls.CurveID{
			tls.GREASE_PLACEHOLDER,
			tls.X25519,
			tls.CurveP256,
			tls.CurveP384,
		},
		KeySharePreferences: []tls.CurveID{
			tls.GREASE_PLACEHOLDER,
			tls.X25519,
		},
		MinVersion: tls.VersionTLS12,
		MaxVersion: tls.VersionTLS13,
		SupportedVersions: []uint16{
			tls.GREASE_PLACEHOLDER,
			tls.VersionTLS13,
			tls.VersionTLS12,
		},
		CertificateCompressionPreferences: []tls.CertificateCompressionAlgorithm{
			tls.Brotli,
		},
		SignatureAlgorithmsPreferences: []tls.SignatureScheme{
			tls.ECDSAWithP256AndSHA256,
			tls.PSSWithSHA256,
			tls.PKCS1WithSHA256,
			tls.ECDSAWithP384AndSHA384,
			tls.PSSWithSHA384,
			tls.PKCS1WithSHA384,
			tls.PSSWithSHA512,
			tls.PKCS1WithSHA512,
		},
		NextProtos:        []string{"h2", "http/1.1"},
		NextProtoSettings: map[string][]byte{"h2": nil},
		ClientHelloPadding: func(pq tls.PaddingRequest) (uint16, bool) {
			if pq.HelloInner || pq.HelloRetryRequest || pq.QUIC {
				return 0, false
			}

			if pq.UnpaddedLength > 0xff && pq.UnpaddedLength < 0x200 {
				paddingLen := 0x200 - pq.UnpaddedLength
				if paddingLen >= 4+1 {
					paddingLen -= 4
				} else {
					paddingLen = 1
				}
				return uint16(paddingLen), true
			}

			return 0, false
		},
		ShuffleExtensions: true,
		EncryptedClientHelloConfig: &tls.ECHConfig{
			Dummy: &tls.ECHDummyConfig{
				CipherSuites: []tls.ECHCipher{
					{KEM: hpke.DHKEM(ecdh.X25519()), KDF: hpke.HKDFSHA256(), AEAD: hpke.AES128GCM()},
				},
				InnerLens: []uint16{128, 160, 192, 224},
			},
			InnerExtensions: []tls.Extension{
				&tls.ServerNameIndicationExtension{},
				&tls.SupportedVersionsExtension{},
				&tls.EncryptedClientHelloExtension{},

				&tls.ECHOuterExtension{},

				&tls.PreSharedKeyExtension{},
			},
			OuterExtensions: []tls.Extension{
				&tls.GREASEExtension{},
				&tls.ServerNameIndicationExtension{},
				&tls.StatusRequestExtension{},
				&tls.SupportedGroupsExtension{},
				&tls.SupportedPointsExtension{},
				&tls.SignatureAlgorithmsExtension{},
				&tls.ALPNExtension{},
				&tls.SCTExtension{},
				&tls.ExtendedMasterSecretExtension{},
				&tls.CompressedCertificateExtension{},
				&tls.SessionTicketExtension{},
				&tls.SupportedVersionsExtension{},
				&tls.CookieExtension{},
				&tls.PSKModesExtension{},
				&tls.KeyShareExtension{},
				&tls.LegacyALPSExtension{},
				&tls.RenegotiationInfoExtension{},
				&tls.EncryptedClientHelloExtension{},
				&tls.GREASEExtension{},
				&tls.PaddingExtension{},
			},
			CompressedExtensions: []tls.Extension{
				&tls.GREASEExtension{},
				&tls.StatusRequestExtension{},
				&tls.SupportedGroupsExtension{},
				&tls.SignatureAlgorithmsExtension{},
				&tls.ALPNExtension{},
				&tls.SCTExtension{},
				&tls.CompressedCertificateExtension{},
				&tls.CookieExtension{},
				&tls.PSKModesExtension{},
				&tls.KeyShareExtension{},
				&tls.LegacyALPSExtension{},
				&tls.GREASEExtension{},
			},
		},
		Extensions: []tls.Extension{
			&tls.GREASEExtension{},
			&tls.ServerNameIndicationExtension{},
			&tls.StatusRequestExtension{},
			&tls.SupportedGroupsExtension{},
			&tls.SupportedPointsExtension{},
			&tls.SignatureAlgorithmsExtension{},
			&tls.ALPNExtension{},
			&tls.SCTExtension{},
			&tls.ExtendedMasterSecretExtension{},
			&tls.CompressedCertificateExtension{},
			&tls.SessionTicketExtension{},
			&tls.SupportedVersionsExtension{},
			&tls.CookieExtension{},
			&tls.PSKModesExtension{},
			&tls.KeyShareExtension{},
			&tls.LegacyALPSExtension{},
			&tls.RenegotiationInfoExtension{},
			&tls.EncryptedClientHelloExtension{},
			&tls.GREASEExtension{},
			&tls.PaddingExtension{},
			&tls.PreSharedKeyExtension{},
		},
		ClientSessionCache: emptyCache,
	},
}
View Source
var Finger_Edge_122_Websocket = Finger{
	JA3: "772,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,5-10-11-13-16-18-23-27-35-43-45-51-17513-65281-65037-21,29-23-24,0",
	Config: &tls.Config{
		Behavior: &tls.Behavior{
			CheckUselessRecordsCount: func(count tls.UselessRecordCount) bool {
				return !(count.ChangeCipherSpec > 32 || count.WarningAlerts > 32 || count.WarningAlerts > 5)
			},
			ChangeCipherSpec: tls.ChangeCipherSpecBehavior{
				DecodeResponse:                alertIllegalParameter,
				DecodeResponseTLS13:           alertBadRecordMAC,
				RejectPlaintextAfterEncrypted: true,
				RejectAfterEncrypted:          true,
			},
			Alert: tls.AlertBehavior{
				DecodeResponse:  alertDecodeError,
				UnknownResponse: alertIllegalParameter,
				LevelCheck:      true,
			},
		},
		CipherSuites: []uint16{
			tls.GREASE_PLACEHOLDER,
			tls.TLS_AES_128_GCM_SHA256,
			tls.TLS_AES_256_GCM_SHA384,
			tls.TLS_CHACHA20_POLY1305_SHA256,
			tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
			tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
			tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
			tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
			tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_RSA_WITH_AES_128_CBC_SHA,
			tls.TLS_RSA_WITH_AES_256_CBC_SHA,
		},
		PreferCipherSuites: true,
		Renegotiation:      tls.RenegotiateOnceAsClient,
		CurvePreferences: []tls.CurveID{
			tls.GREASE_PLACEHOLDER,
			tls.X25519,
			tls.CurveP256,
			tls.CurveP384,
		},
		KeySharePreferences: []tls.CurveID{
			tls.GREASE_PLACEHOLDER,
			tls.X25519,
		},
		MinVersion: tls.VersionTLS12,
		MaxVersion: tls.VersionTLS13,
		SupportedVersions: []uint16{
			tls.GREASE_PLACEHOLDER,
			tls.VersionTLS13,
			tls.VersionTLS12,
		},
		CertificateCompressionPreferences: []tls.CertificateCompressionAlgorithm{
			tls.Brotli,
		},
		SignatureAlgorithmsPreferences: []tls.SignatureScheme{
			tls.ECDSAWithP256AndSHA256,
			tls.PSSWithSHA256,
			tls.PKCS1WithSHA256,
			tls.ECDSAWithP384AndSHA384,
			tls.PSSWithSHA384,
			tls.PKCS1WithSHA384,
			tls.PSSWithSHA512,
			tls.PKCS1WithSHA512,
		},
		NextProtos:        []string{"http/1.1"},
		NextProtoSettings: map[string][]byte{"h2": nil},
		ClientHelloPadding: func(pq tls.PaddingRequest) (uint16, bool) {
			if pq.HelloInner || pq.HelloRetryRequest || pq.QUIC {
				return 0, false
			}

			if pq.UnpaddedLength > 0xff && pq.UnpaddedLength < 0x200 {
				paddingLen := 0x200 - pq.UnpaddedLength
				if paddingLen >= 4+1 {
					paddingLen -= 4
				} else {
					paddingLen = 1
				}
				return uint16(paddingLen), true
			}

			return 0, false
		},
		ShuffleExtensions: true,
		EncryptedClientHelloConfig: &tls.ECHConfig{
			Dummy: &tls.ECHDummyConfig{
				CipherSuites: []tls.ECHCipher{
					{KEM: hpke.DHKEM(ecdh.X25519()), KDF: hpke.HKDFSHA256(), AEAD: hpke.AES128GCM()},
				},
				InnerLens: []uint16{128, 160, 192, 224},
			},
			InnerExtensions: []tls.Extension{
				&tls.ServerNameIndicationExtension{},
				&tls.SupportedVersionsExtension{},
				&tls.EncryptedClientHelloExtension{},

				&tls.ECHOuterExtension{},

				&tls.PreSharedKeyExtension{},
			},
			OuterExtensions: []tls.Extension{
				&tls.GREASEExtension{},
				&tls.ServerNameIndicationExtension{},
				&tls.StatusRequestExtension{},
				&tls.SupportedGroupsExtension{},
				&tls.SupportedPointsExtension{},
				&tls.SignatureAlgorithmsExtension{},
				&tls.ALPNExtension{},
				&tls.SCTExtension{},
				&tls.ExtendedMasterSecretExtension{},
				&tls.CompressedCertificateExtension{},
				&tls.SessionTicketExtension{},
				&tls.SupportedVersionsExtension{},
				&tls.CookieExtension{},
				&tls.PSKModesExtension{},
				&tls.KeyShareExtension{},
				&tls.LegacyALPSExtension{},
				&tls.RenegotiationInfoExtension{},
				&tls.EncryptedClientHelloExtension{},
				&tls.GREASEExtension{},
				&tls.PaddingExtension{},
			},
			CompressedExtensions: []tls.Extension{
				&tls.GREASEExtension{},
				&tls.StatusRequestExtension{},
				&tls.SupportedGroupsExtension{},
				&tls.SignatureAlgorithmsExtension{},
				&tls.ALPNExtension{},
				&tls.SCTExtension{},
				&tls.CompressedCertificateExtension{},
				&tls.CookieExtension{},
				&tls.PSKModesExtension{},
				&tls.KeyShareExtension{},
				&tls.LegacyALPSExtension{},
				&tls.GREASEExtension{},
			},
		},
		Extensions: []tls.Extension{
			&tls.GREASEExtension{},
			&tls.ServerNameIndicationExtension{},
			&tls.StatusRequestExtension{},
			&tls.SupportedGroupsExtension{},
			&tls.SupportedPointsExtension{},
			&tls.SignatureAlgorithmsExtension{},
			&tls.ALPNExtension{},
			&tls.SCTExtension{},
			&tls.ExtendedMasterSecretExtension{},
			&tls.CompressedCertificateExtension{},
			&tls.SessionTicketExtension{},
			&tls.SupportedVersionsExtension{},
			&tls.CookieExtension{},
			&tls.PSKModesExtension{},
			&tls.KeyShareExtension{},
			&tls.LegacyALPSExtension{},
			&tls.RenegotiationInfoExtension{},
			&tls.EncryptedClientHelloExtension{},
			&tls.GREASEExtension{},
			&tls.PaddingExtension{},
			&tls.PreSharedKeyExtension{},
		},
		ClientSessionCache: emptyCache,
	},
}
View Source
var Finger_Edge_140 = Finger{
	JA3: "772,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,5-10-11-13-16-18-23-27-35-43-45-51-17613-65281-65037,4588-29-23-24,0",
	Config: &tls.Config{
		Behavior: &tls.Behavior{
			CheckUselessRecordsCount: func(count tls.UselessRecordCount) bool {
				return !(count.ChangeCipherSpec > 32 || count.WarningAlerts > 32 || count.WarningAlerts > 5)
			},
			ChangeCipherSpec: tls.ChangeCipherSpecBehavior{
				DecodeResponse:                alertIllegalParameter,
				DecodeResponseTLS13:           alertBadRecordMAC,
				RejectPlaintextAfterEncrypted: true,
				RejectAfterEncrypted:          true,
			},
			Alert: tls.AlertBehavior{
				DecodeResponse:  alertDecodeError,
				UnknownResponse: alertIllegalParameter,
				LevelCheck:      true,
			},
		},
		CipherSuites: []uint16{
			tls.GREASE_PLACEHOLDER,
			tls.TLS_AES_128_GCM_SHA256,
			tls.TLS_AES_256_GCM_SHA384,
			tls.TLS_CHACHA20_POLY1305_SHA256,
			tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
			tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
			tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
			tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
			tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_RSA_WITH_AES_128_CBC_SHA,
			tls.TLS_RSA_WITH_AES_256_CBC_SHA,
		},
		PreferCipherSuites: true,
		Renegotiation:      tls.RenegotiateOnceAsClient,
		CurvePreferences: []tls.CurveID{
			tls.GREASE_PLACEHOLDER,
			tls.X25519MLKEM768,
			tls.X25519,
			tls.CurveP256,
			tls.CurveP384,
		},
		IndependentlyHybridKeyShare: true,
		KeySharePreferences: []tls.CurveID{
			tls.GREASE_PLACEHOLDER,
			tls.X25519MLKEM768,
			tls.X25519,
		},
		MinVersion: tls.VersionTLS12,
		MaxVersion: tls.VersionTLS13,
		SupportedVersions: []uint16{
			tls.GREASE_PLACEHOLDER,
			tls.VersionTLS13,
			tls.VersionTLS12,
		},
		CertificateCompressionPreferences: []tls.CertificateCompressionAlgorithm{
			tls.Brotli,
		},
		SignatureAlgorithmsPreferences: []tls.SignatureScheme{
			tls.ECDSAWithP256AndSHA256,
			tls.PSSWithSHA256,
			tls.PKCS1WithSHA256,
			tls.ECDSAWithP384AndSHA384,
			tls.PSSWithSHA384,
			tls.PKCS1WithSHA384,
			tls.PSSWithSHA512,
			tls.PKCS1WithSHA512,
		},
		NextProtos:        []string{"h2", "http/1.1"},
		NextProtoSettings: map[string][]byte{"h2": nil},
		ClientHelloPadding: func(pq tls.PaddingRequest) (uint16, bool) {
			if pq.HelloInner || pq.HelloRetryRequest || pq.QUIC {
				return 0, false
			}

			if pq.UnpaddedLength > 0xff && pq.UnpaddedLength < 0x200 {
				paddingLen := 0x200 - pq.UnpaddedLength
				if paddingLen >= 4+1 {
					paddingLen -= 4
				} else {
					paddingLen = 1
				}
				return uint16(paddingLen), true
			}

			return 0, false
		},
		ShuffleExtensions: true,
		EncryptedClientHelloConfig: &tls.ECHConfig{
			Dummy: &tls.ECHDummyConfig{
				CipherSuites: []tls.ECHCipher{
					{KEM: hpke.DHKEM(ecdh.X25519()), KDF: hpke.HKDFSHA256(), AEAD: hpke.AES128GCM()},
				},
				InnerLens: []uint16{128, 160, 192, 224},
			},
			InnerExtensions: []tls.Extension{
				&tls.ServerNameIndicationExtension{},
				&tls.SupportedVersionsExtension{},
				&tls.EncryptedClientHelloExtension{},

				&tls.ECHOuterExtension{},

				&tls.PreSharedKeyExtension{},
			},
			OuterExtensions: []tls.Extension{
				&tls.GREASEExtension{},
				&tls.ServerNameIndicationExtension{},
				&tls.StatusRequestExtension{},
				&tls.SupportedGroupsExtension{},
				&tls.SupportedPointsExtension{},
				&tls.SignatureAlgorithmsExtension{},
				&tls.ALPNExtension{},
				&tls.SCTExtension{},
				&tls.ExtendedMasterSecretExtension{},
				&tls.CompressedCertificateExtension{},
				&tls.SessionTicketExtension{},
				&tls.SupportedVersionsExtension{},
				&tls.CookieExtension{},
				&tls.PSKModesExtension{},
				&tls.KeyShareExtension{},
				&tls.ALPSExtension{},
				&tls.RenegotiationInfoExtension{},
				&tls.EncryptedClientHelloExtension{},
				&tls.GREASEExtension{},
				&tls.PaddingExtension{},
			},
			CompressedExtensions: []tls.Extension{
				&tls.GREASEExtension{},
				&tls.StatusRequestExtension{},
				&tls.SupportedGroupsExtension{},
				&tls.SignatureAlgorithmsExtension{},
				&tls.ALPNExtension{},
				&tls.SCTExtension{},
				&tls.CompressedCertificateExtension{},
				&tls.CookieExtension{},
				&tls.PSKModesExtension{},
				&tls.KeyShareExtension{},
				&tls.ALPSExtension{},
				&tls.GREASEExtension{},
			},
		},
		Extensions: []tls.Extension{
			&tls.GREASEExtension{},
			&tls.ServerNameIndicationExtension{},
			&tls.StatusRequestExtension{},
			&tls.SupportedGroupsExtension{},
			&tls.SupportedPointsExtension{},
			&tls.SignatureAlgorithmsExtension{},
			&tls.ALPNExtension{},
			&tls.SCTExtension{},
			&tls.ExtendedMasterSecretExtension{},
			&tls.CompressedCertificateExtension{},
			&tls.SessionTicketExtension{},
			&tls.SupportedVersionsExtension{},
			&tls.CookieExtension{},
			&tls.PSKModesExtension{},
			&tls.KeyShareExtension{},
			&tls.ALPSExtension{},
			&tls.RenegotiationInfoExtension{},
			&tls.EncryptedClientHelloExtension{},
			&tls.GREASEExtension{},
			&tls.PaddingExtension{},
			&tls.PreSharedKeyExtension{},
		},
		ClientSessionCache: emptyCache,
	},
}
View Source
var Finger_Edge_140_Websocket = Finger{
	JA3: "772,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,5-10-11-13-16-18-23-27-35-43-45-51-17613-65281-65037,4588-29-23-24,0",
	Config: &tls.Config{
		Behavior: &tls.Behavior{
			CheckUselessRecordsCount: func(count tls.UselessRecordCount) bool {
				return !(count.ChangeCipherSpec > 32 || count.WarningAlerts > 32 || count.WarningAlerts > 5)
			},
			ChangeCipherSpec: tls.ChangeCipherSpecBehavior{
				DecodeResponse:                alertIllegalParameter,
				DecodeResponseTLS13:           alertBadRecordMAC,
				RejectPlaintextAfterEncrypted: true,
				RejectAfterEncrypted:          true,
			},
			Alert: tls.AlertBehavior{
				DecodeResponse:  alertDecodeError,
				UnknownResponse: alertIllegalParameter,
				LevelCheck:      true,
			},
		},
		CipherSuites: []uint16{
			tls.GREASE_PLACEHOLDER,
			tls.TLS_AES_128_GCM_SHA256,
			tls.TLS_AES_256_GCM_SHA384,
			tls.TLS_CHACHA20_POLY1305_SHA256,
			tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
			tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
			tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
			tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
			tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_RSA_WITH_AES_128_CBC_SHA,
			tls.TLS_RSA_WITH_AES_256_CBC_SHA,
		},
		PreferCipherSuites: true,
		Renegotiation:      tls.RenegotiateOnceAsClient,
		CurvePreferences: []tls.CurveID{
			tls.GREASE_PLACEHOLDER,
			tls.X25519MLKEM768,
			tls.X25519,
			tls.CurveP256,
			tls.CurveP384,
		},
		IndependentlyHybridKeyShare: true,
		KeySharePreferences: []tls.CurveID{
			tls.GREASE_PLACEHOLDER,
			tls.X25519MLKEM768,
			tls.X25519,
		},
		MinVersion: tls.VersionTLS12,
		MaxVersion: tls.VersionTLS13,
		SupportedVersions: []uint16{
			tls.GREASE_PLACEHOLDER,
			tls.VersionTLS13,
			tls.VersionTLS12,
		},
		CertificateCompressionPreferences: []tls.CertificateCompressionAlgorithm{
			tls.Brotli,
		},
		SignatureAlgorithmsPreferences: []tls.SignatureScheme{
			tls.ECDSAWithP256AndSHA256,
			tls.PSSWithSHA256,
			tls.PKCS1WithSHA256,
			tls.ECDSAWithP384AndSHA384,
			tls.PSSWithSHA384,
			tls.PKCS1WithSHA384,
			tls.PSSWithSHA512,
			tls.PKCS1WithSHA512,
		},
		NextProtos:        []string{"http/1.1"},
		NextProtoSettings: map[string][]byte{"h2": nil},
		ClientHelloPadding: func(pq tls.PaddingRequest) (uint16, bool) {
			if pq.HelloInner || pq.HelloRetryRequest || pq.QUIC {
				return 0, false
			}

			if pq.UnpaddedLength > 0xff && pq.UnpaddedLength < 0x200 {
				paddingLen := 0x200 - pq.UnpaddedLength
				if paddingLen >= 4+1 {
					paddingLen -= 4
				} else {
					paddingLen = 1
				}
				return uint16(paddingLen), true
			}

			return 0, false
		},
		ShuffleExtensions: true,
		EncryptedClientHelloConfig: &tls.ECHConfig{
			Dummy: &tls.ECHDummyConfig{
				CipherSuites: []tls.ECHCipher{
					{KEM: hpke.DHKEM(ecdh.X25519()), KDF: hpke.HKDFSHA256(), AEAD: hpke.AES128GCM()},
				},
				InnerLens: []uint16{128, 160, 192, 224},
			},
			InnerExtensions: []tls.Extension{
				&tls.ServerNameIndicationExtension{},
				&tls.SupportedVersionsExtension{},
				&tls.EncryptedClientHelloExtension{},

				&tls.ECHOuterExtension{},

				&tls.PreSharedKeyExtension{},
			},
			OuterExtensions: []tls.Extension{
				&tls.GREASEExtension{},
				&tls.ServerNameIndicationExtension{},
				&tls.StatusRequestExtension{},
				&tls.SupportedGroupsExtension{},
				&tls.SupportedPointsExtension{},
				&tls.SignatureAlgorithmsExtension{},
				&tls.ALPNExtension{},
				&tls.SCTExtension{},
				&tls.ExtendedMasterSecretExtension{},
				&tls.CompressedCertificateExtension{},
				&tls.SessionTicketExtension{},
				&tls.SupportedVersionsExtension{},
				&tls.CookieExtension{},
				&tls.PSKModesExtension{},
				&tls.KeyShareExtension{},
				&tls.ALPSExtension{},
				&tls.RenegotiationInfoExtension{},
				&tls.EncryptedClientHelloExtension{},
				&tls.GREASEExtension{},
				&tls.PaddingExtension{},
			},
			CompressedExtensions: []tls.Extension{
				&tls.GREASEExtension{},
				&tls.StatusRequestExtension{},
				&tls.SupportedGroupsExtension{},
				&tls.SignatureAlgorithmsExtension{},
				&tls.ALPNExtension{},
				&tls.SCTExtension{},
				&tls.CompressedCertificateExtension{},
				&tls.CookieExtension{},
				&tls.PSKModesExtension{},
				&tls.KeyShareExtension{},
				&tls.ALPSExtension{},
				&tls.GREASEExtension{},
			},
		},
		Extensions: []tls.Extension{
			&tls.GREASEExtension{},
			&tls.ServerNameIndicationExtension{},
			&tls.StatusRequestExtension{},
			&tls.SupportedGroupsExtension{},
			&tls.SupportedPointsExtension{},
			&tls.SignatureAlgorithmsExtension{},
			&tls.ALPNExtension{},
			&tls.SCTExtension{},
			&tls.ExtendedMasterSecretExtension{},
			&tls.CompressedCertificateExtension{},
			&tls.SessionTicketExtension{},
			&tls.SupportedVersionsExtension{},
			&tls.CookieExtension{},
			&tls.PSKModesExtension{},
			&tls.KeyShareExtension{},
			&tls.ALPSExtension{},
			&tls.RenegotiationInfoExtension{},
			&tls.EncryptedClientHelloExtension{},
			&tls.GREASEExtension{},
			&tls.PaddingExtension{},
			&tls.PreSharedKeyExtension{},
		},
		ClientSessionCache: emptyCache,
	},
}
View Source
var Finger_Firefox_144 = Finger{
	JA3: "772,4865-4867-4866-49195-49199-52393-52392-49196-49200-49162-49161-49171-49172-156-157-47-53,23-65281-10-11-35-16-5-34-18-51-43-13-45-28-27-65037,4588-29-23-24-25-256-257,0",
	Config: &tls.Config{
		Behavior: &tls.Behavior{
			CheckUselessRecordsCount: func(count tls.UselessRecordCount) bool {
				return !(count.ChangeCipherSpec > 1)
			},
			ChangeCipherSpec: tls.ChangeCipherSpecBehavior{
				DecodeResponse:       alertUnexpectedMessage,
				RejectAfterEncrypted: true,
			},
			Alert: tls.AlertBehavior{
				DecodeResponse:                 alertDecodeError,
				UnknownAsWarning:               true,
				DisableIgnoreFatalUserCanceled: true,
			},
		},
		CipherSuites: []uint16{
			tls.TLS_AES_128_GCM_SHA256,
			tls.TLS_CHACHA20_POLY1305_SHA256,
			tls.TLS_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
			tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
			tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
			tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
			tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
			tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
			tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_RSA_WITH_AES_128_CBC_SHA,
			tls.TLS_RSA_WITH_AES_256_CBC_SHA,
		},
		PreferCipherSuites: true,
		Renegotiation:      tls.RenegotiateOnceAsClient,
		CurvePreferences: []tls.CurveID{
			tls.X25519MLKEM768,
			tls.X25519,
			tls.CurveP256,
			tls.CurveP384,
			tls.CurveP521,
			tls.FFDHE2048,
			tls.FFDHE3072,
		},
		KeySharePreferences: []tls.CurveID{
			tls.X25519MLKEM768,
			tls.X25519,
			tls.CurveP256,
		},
		MinVersion: tls.VersionTLS12,
		MaxVersion: tls.VersionTLS13,
		SupportedVersions: []uint16{
			tls.GREASE_PLACEHOLDER,
			tls.VersionTLS13,
			tls.VersionTLS12,
		},
		CertificateCompressionPreferences: []tls.CertificateCompressionAlgorithm{
			tls.Zlib,
			tls.Brotli,
			tls.Zstd,
		},
		SignatureAlgorithmsPreferences: []tls.SignatureScheme{
			tls.ECDSAWithP256AndSHA256,
			tls.ECDSAWithP384AndSHA384,
			tls.ECDSAWithP521AndSHA512,
			tls.PSSWithSHA256,
			tls.PSSWithSHA384,
			tls.PSSWithSHA512,
			tls.PKCS1WithSHA256,
			tls.PKCS1WithSHA384,
			tls.PKCS1WithSHA512,
			tls.ECDSAWithSHA1,
			tls.PKCS1WithSHA1,
		},
		DelegatedCredential: true,
		DelegatedCredentialPreferences: []tls.SignatureScheme{
			tls.ECDSAWithP256AndSHA256,
			tls.ECDSAWithP384AndSHA384,
			tls.ECDSAWithP521AndSHA512,
			tls.ECDSAWithSHA1,
		},
		NextProtos: []string{"h2", "http/1.1"},
		ClientHelloPadding: func(pq tls.PaddingRequest) (uint16, bool) {
			if pq.HelloInner || pq.HelloRetryRequest || pq.QUIC {
				return 0, false
			}

			if pq.UnpaddedLength > 0xff && pq.UnpaddedLength < 0x200 {
				paddingLen := 0x200 - pq.UnpaddedLength
				if paddingLen >= 4+1 {
					paddingLen -= 4
				} else {
					paddingLen = 1
				}
				return uint16(paddingLen), true
			}

			return 0, false
		},
		EncryptedClientHelloConfig: &tls.ECHConfig{
			Dummy: &tls.ECHDummyConfig{
				CipherSuites: []tls.ECHCipher{
					{KEM: hpke.DHKEM(ecdh.X25519()), KDF: hpke.HKDFSHA256(), AEAD: hpke.AES128GCM()},
					{KEM: hpke.DHKEM(ecdh.X25519()), KDF: hpke.HKDFSHA256(), AEAD: hpke.ChaCha20Poly1305()},
				},
				InnerLens: []uint16{224},
			},
			KeepCipherSuites: true,
			InnerExtensions: []tls.Extension{
				&tls.EncryptedClientHelloExtension{},
				&tls.ServerNameIndicationExtension{},
				&tls.SupportedVersionsExtension{},

				&tls.ECHOuterExtension{},

				&tls.PreSharedKeyExtension{},
			},
			OuterExtensions: []tls.Extension{
				&tls.ServerNameIndicationExtension{},
				&tls.ExtendedMasterSecretExtension{},
				&tls.RenegotiationInfoExtension{},
				&tls.SupportedGroupsExtension{},
				&tls.SupportedPointsExtension{},
				&tls.SessionTicketExtension{},
				&tls.ALPNExtension{},
				&tls.StatusRequestExtension{},
				&tls.DelegatedCredentialsExtension{},
				&tls.SCTExtension{},
				&tls.KeyShareExtension{},
				&tls.SupportedVersionsExtension{},
				&tls.EarlyDataExtension{},
				&tls.SignatureAlgorithmsExtension{},
				&tls.PSKModesExtension{},
				&tls.RecordSizeLimitExtension{},
				&tls.CompressedCertificateExtension{},
				&tls.EncryptedClientHelloExtension{},
				&tls.PaddingExtension{},
				&tls.PreSharedKeyExtension{},
			},
			CompressedExtensions: []tls.Extension{
				&tls.SupportedGroupsExtension{},
				&tls.ALPNExtension{},
				&tls.StatusRequestExtension{},
				&tls.DelegatedCredentialsExtension{},
				&tls.SCTExtension{},
				&tls.KeyShareExtension{},
				&tls.EarlyDataExtension{},
				&tls.SignatureAlgorithmsExtension{},
				&tls.PSKModesExtension{},
				&tls.RecordSizeLimitExtension{},
				&tls.CompressedCertificateExtension{},
			},
		},
		MaxRecordSize:  16385,
		AllowEarlyData: true,
		Extensions: []tls.Extension{
			&tls.ServerNameIndicationExtension{},
			&tls.ExtendedMasterSecretExtension{},
			&tls.RenegotiationInfoExtension{},
			&tls.SupportedGroupsExtension{},
			&tls.SupportedPointsExtension{},
			&tls.SessionTicketExtension{},
			&tls.ALPNExtension{},
			&tls.StatusRequestExtension{},
			&tls.DelegatedCredentialsExtension{},
			&tls.SCTExtension{},
			&tls.KeyShareExtension{},
			&tls.SupportedVersionsExtension{},
			&tls.EarlyDataExtension{},
			&tls.SignatureAlgorithmsExtension{},
			&tls.PSKModesExtension{},
			&tls.RecordSizeLimitExtension{},
			&tls.CompressedCertificateExtension{},
			&tls.EncryptedClientHelloExtension{},
			&tls.PaddingExtension{},
			&tls.PreSharedKeyExtension{},
		},
		ClientSessionCache: emptyCache,
	},
}
View Source
var Finger_Safari_18_7 = Finger{
	JA3: "772,4865-4866-4867-49196-49195-52393-49200-49199-52392-49162-49161-49172-49171-157-156-53-47-49160-49170-10,23-65281-10-11-16-5-13-18-51-45-43-27-21,29-23-24-25,0",
	Config: &tls.Config{
		Behavior: &tls.Behavior{
			CheckUselessRecordsCount: func(count tls.UselessRecordCount) bool {
				return !(count.ChangeCipherSpec > 32 || count.WarningAlerts > 32 || count.WarningAlerts > 5)
			},
			ChangeCipherSpec: tls.ChangeCipherSpecBehavior{
				DecodeResponse:                alertIllegalParameter,
				DecodeResponseTLS13:           alertBadRecordMAC,
				RejectPlaintextAfterEncrypted: true,
				RejectAfterEncrypted:          true,
			},
			Alert: tls.AlertBehavior{
				DecodeResponse:                 alertDecodeError,
				UnknownResponse:                alertIllegalParameter,
				LevelCheck:                     true,
				DisableIgnoreFatalUserCanceled: true,
			},
		},
		CipherSuites: []uint16{
			tls.GREASE_PLACEHOLDER,
			tls.TLS_AES_128_GCM_SHA256,
			tls.TLS_AES_256_GCM_SHA384,
			tls.TLS_CHACHA20_POLY1305_SHA256,
			tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
			tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
			tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
			tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
			tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
			tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
			tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_RSA_WITH_AES_256_CBC_SHA,
			tls.TLS_RSA_WITH_AES_128_CBC_SHA,
			tls.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
			tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
			tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
		},
		PreferCipherSuites: true,
		Renegotiation:      tls.RenegotiateOnceAsClient,
		CurvePreferences: []tls.CurveID{
			tls.GREASE_PLACEHOLDER,
			tls.X25519,
			tls.CurveP256,
			tls.CurveP384,
			tls.CurveP521,
		},
		KeySharePreferences: []tls.CurveID{
			tls.GREASE_PLACEHOLDER,
			tls.X25519,
		},
		MinVersion: tls.VersionTLS10,
		MaxVersion: tls.VersionTLS13,
		SupportedVersions: []uint16{
			tls.GREASE_PLACEHOLDER,
			tls.VersionTLS13,
			tls.VersionTLS12,
			tls.VersionTLS11,
			tls.VersionTLS10,
		},
		CertificateCompressionPreferences: []tls.CertificateCompressionAlgorithm{
			tls.Zlib,
		},
		SignatureAlgorithmsPreferences: []tls.SignatureScheme{
			tls.ECDSAWithP256AndSHA256,
			tls.PSSWithSHA256,
			tls.PKCS1WithSHA256,
			tls.ECDSAWithP384AndSHA384,
			tls.PSSWithSHA384,
			tls.PSSWithSHA384,
			tls.PKCS1WithSHA384,
			tls.PSSWithSHA512,
			tls.PKCS1WithSHA512,
			tls.PKCS1WithSHA1,
		},
		NextProtos: []string{"h2", "http/1.1"},
		ClientHelloPadding: func(pq tls.PaddingRequest) (uint16, bool) {
			if pq.HelloInner || pq.HelloRetryRequest || pq.QUIC {
				return 0, false
			}

			if pq.UnpaddedLength > 0xff && pq.UnpaddedLength < 0x200 {
				paddingLen := 0x200 - pq.UnpaddedLength
				if paddingLen >= 4+1 {
					paddingLen -= 4
				} else {
					paddingLen = 1
				}
				return uint16(paddingLen), true
			}

			return 0, false
		},
		Extensions: []tls.Extension{
			&tls.GREASEExtension{},
			&tls.ServerNameIndicationExtension{},
			&tls.ExtendedMasterSecretExtension{},
			&tls.RenegotiationInfoExtension{},
			&tls.SupportedGroupsExtension{},
			&tls.SupportedPointsExtension{},
			&tls.ALPNExtension{},
			&tls.StatusRequestExtension{},
			&tls.SignatureAlgorithmsExtension{},
			&tls.SCTExtension{},
			&tls.KeyShareExtension{},
			&tls.PSKModesExtension{},
			&tls.SupportedVersionsExtension{},
			&tls.CompressedCertificateExtension{},
			&tls.GREASEExtension{},
			&tls.PaddingExtension{},
		},
		EncryptedClientHelloConfig: &tls.ECHConfig{
			Disabled: true,
		},
		ClientSessionCache: emptyCache,
	},
}

Functions

func JA3

func JA3(ch *tls.ClientHelloInfo) string

func TLSConfig

func TLSConfig(finger Finger, config *Config) *tls.Config

Types

type Config

type Config struct {
	Rand                                io.Reader
	Time                                func() time.Time
	Certificates                        []tls.Certificate
	NameToCertificate                   map[string]*tls.Certificate
	GetCertificate                      func(*tls.ClientHelloInfo) (*tls.Certificate, error)
	GetClientCertificate                func(*tls.CertificateRequestInfo) (*tls.Certificate, error)
	GetConfigForClient                  func(*tls.ClientHelloInfo) (*tls.Config, error)
	VerifyPeerCertificate               func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error
	VerifyConnection                    func(tls.ConnectionState) error
	RootCAs                             *x509.CertPool
	ServerName                          string
	ClientAuth                          tls.ClientAuthType
	ClientCAs                           *x509.CertPool
	InsecureSkipVerify                  bool
	ClientSessionCache                  tls.ClientSessionCache
	UnwrapSession                       func(identity []byte, cs tls.ConnectionState) (*tls.SessionState, error)
	WrapSession                         func(tls.ConnectionState, *tls.SessionState) ([]byte, error)
	DynamicRecordSizingDisabled         bool
	AllowEarlyData                      bool
	KeyLogWriter                        io.Writer
	KernelTX, KernelRX                  bool
	KernelRXExpectNoPad                 bool
	EncryptedClientHelloConfigList      []byte
	EncryptedClientHelloRejectionVerify func(tls.ConnectionState) error
	GetEncryptedClientHelloKeys         func(*tls.ClientHelloInfo) ([]tls.EncryptedClientHelloKey, error)
	EncryptedClientHelloKeys            []tls.EncryptedClientHelloKey
}

type Finger

type Finger struct {
	JA3 string
	*tls.Config
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL