diff --git a/example/main.go b/example/main.go index f7d98ce..344ca1d 100644 --- a/example/main.go +++ b/example/main.go @@ -25,6 +25,7 @@ func main() { postAsTlsClient() requestWithFollowRedirectSwitch() requestWithCustomClient() + requestWithJa3CustomClientWithTwoGreaseExtensions() rotateProxiesOnClient() downloadImageWithTlsClient() testPskExtension() @@ -689,6 +690,103 @@ func requestWithCustomClient() { log.Printf("requesting topps as customClient1 => status code: %d\n", resp.StatusCode) } +func requestWithJa3CustomClientWithTwoGreaseExtensions() { + settings := map[http2.SettingID]uint32{ + http2.SettingHeaderTableSize: 65536, + http2.SettingEnablePush: 0, + http2.SettingInitialWindowSize: 6291456, + http2.SettingMaxHeaderListSize: 262144, + } + settingsOrder := []http2.SettingID{ + http2.SettingHeaderTableSize, + http2.SettingEnablePush, + http2.SettingInitialWindowSize, + http2.SettingMaxHeaderListSize, + } + + pseudoHeaderOrder := []string{ + ":method", + ":authority", + ":scheme", + ":path", + } + + connectionFlow := uint32(15663105) + + ja3String := "771,2570-4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,2570-18-5-27-11-0-10-35-16-65037-51-13-23-43-17513-65281-45-2570,2570-25497-29-23-24,0" + + supportedSignatureAlgorithms := []string{ + "ECDSAWithP256AndSHA256", + "PSSWithSHA256", + "PKCS1WithSHA256", + "ECDSAWithP384AndSHA384", + "PSSWithSHA384", + "PKCS1WithSHA384", + "PSSWithSHA512", + "PKCS1WithSHA512", + } + var supportedDelegatedCredentialsAlgorithms []string + supportedVersions := []string{"GREASE", "1.3", "1.2"} + keyShareCurves := []string{"GREASE", "X25519Kyber768", "X25519"} + supportedProtocolsALPN := []string{"h2", "http/1.1"} + supportedProtocolsALPS := []string{"h2"} + echCandidateCipherSuites := []tls_client.CandidateCipherSuites{ + { + KdfId: "HKDF_SHA256", + AeadId: "AEAD_AES_128_GCM", + }, + { + KdfId: "HKDF_SHA256", + AeadId: "AEAD_CHACHA20_POLY1305", + }, + } + candidatePayloads := []uint16{128, 160, 192, 224} + certCompressionAlgo := "brotli" + + specFactory, err := tls_client.GetSpecFactoryFromJa3String(ja3String, supportedSignatureAlgorithms, supportedDelegatedCredentialsAlgorithms, supportedVersions, keyShareCurves, supportedProtocolsALPN, supportedProtocolsALPS, echCandidateCipherSuites, candidatePayloads, certCompressionAlgo) + + customClientProfile := profiles.NewClientProfile(tls.ClientHelloID{ + Client: "MyCustomProfile", + Version: "1", + Seed: nil, + SpecFactory: specFactory, + }, settings, settingsOrder, pseudoHeaderOrder, connectionFlow, nil, nil) + + options := []tls_client.HttpClientOption{ + tls_client.WithTimeoutSeconds(60), + tls_client.WithClientProfile(customClientProfile), // use custom profile here + } + + client, err := tls_client.NewHttpClient(tls_client.NewNoopLogger(), options...) + if err != nil { + log.Println(err) + return + } + + req, err := http.NewRequest(http.MethodGet, "https://tls.browserleaks.com/tls", nil) + if err != nil { + log.Println(err) + return + } + + resp, err := client.Do(req) + if err != nil { + log.Println(err) + return + } + + defer resp.Body.Close() + + readBytes, err := io.ReadAll(resp.Body) + if err != nil { + log.Println(err) + return + } + + log.Printf(string(readBytes)) + log.Printf("status code: %d\n", resp.StatusCode) +} + func testPskExtension() { settings := map[http2.SettingID]uint32{ http2.SettingHeaderTableSize: 65536, diff --git a/ja3.go b/ja3.go index 08d6410..36f3370 100644 --- a/ja3.go +++ b/ja3.go @@ -193,6 +193,12 @@ func stringToSpec(ja3 string, signatureAlgorithms []tls.SignatureScheme, delegat return tls.ClientHelloSpec{}, err } + if uint16(eId) == tls.GREASE_PLACEHOLDER { + // if we use multiple grease extensions with need to generate always a new value. therefore we are creating a new instance here + exts = append(exts, &tls.UtlsGREASEExtension{}) + continue + } + te, ok := extMap[uint16(eId)] if !ok { return tls.ClientHelloSpec{}, fmt.Errorf("unknown extension with id %s provided", e) @@ -211,7 +217,7 @@ func stringToSpec(ja3 string, signatureAlgorithms []tls.SignatureScheme, delegat return tls.ClientHelloSpec{ CipherSuites: suites, - CompressionMethods: []byte{0}, + CompressionMethods: []byte{tls.CompressionNone}, Extensions: exts, GetSessionID: sha256.Sum256, }, nil @@ -219,7 +225,9 @@ func stringToSpec(ja3 string, signatureAlgorithms []tls.SignatureScheme, delegat func getExtensionBaseMap() map[uint16]tls.TLSExtension { return map[uint16]tls.TLSExtension{ - tls.GREASE_PLACEHOLDER: &tls.UtlsGREASEExtension{}, + // This extension needs to be instantiated every time and not be reused if it occurs multiple times in the same ja3 + //tls.GREASE_PLACEHOLDER: &tls.UtlsGREASEExtension{}, + tls.ExtensionServerName: &tls.SNIExtension{}, tls.ExtensionStatusRequest: &tls.StatusRequestExtension{}, diff --git a/tests/client_test_utils.go b/tests/client_test_utils.go index d4ecef1..aa8f26e 100644 --- a/tests/client_test_utils.go +++ b/tests/client_test_utils.go @@ -85,204 +85,204 @@ var clientFingerprints = map[string]map[string]map[string]string{ profiles.Chrome_124.GetClientHelloStr(): map[string]string{ ja3String: "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,27-18-23-17513-16-43-13-11-0-35-10-65037-5-65281-45-51,25497-29-23-24,0", ja3Hash: "64aff24dbef210f33880d4f62e1493dd", - akamaiFingerprint: "1:65536,2:0,4:6291456,6:262144|15663105|0|m,a,s,p", - akamaiFingerprintHash: "90224459f8bf70b7d0a8797eb916dbc9", + akamaiFingerprint: "1:65536;2:0;4:6291456;6:262144|15663105|0|m,a,s,p", + akamaiFingerprintHash: "52d84b11737d980aef856699f885ca86", }, profiles.Chrome_120.GetClientHelloStr(): map[string]string{ ja3String: "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-45-43-5-23-35-13-65281-16-65037-18-51-10-11-17513-27,29-23-24,0", ja3Hash: "1d9a054bac1eef41f30d370f9bbb2ad2", - akamaiFingerprint: "1:65536,2:0,4:6291456,6:262144|15663105|0|m,a,s,p", - akamaiFingerprintHash: "90224459f8bf70b7d0a8797eb916dbc9", + akamaiFingerprint: "1:65536;2:0;4:6291456;6:262144|15663105|0|m,a,s,p", + akamaiFingerprintHash: "52d84b11737d980aef856699f885ca86", }, profiles.Chrome_117.GetClientHelloStr(): map[string]string{ ja3String: "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,45-0-16-13-43-17513-10-23-35-27-18-5-51-65281-11-21,29-23-24,0", ja3Hash: "1ddf8a0ebd957d10c1ab320b10450028", - akamaiFingerprint: "1:65536,2:0,4:6291456,6:262144|15663105|0|m,a,s,p", - akamaiFingerprintHash: "90224459f8bf70b7d0a8797eb916dbc9", + akamaiFingerprint: "1:65536;2:0;4:6291456;6:262144|15663105|0|m,a,s,p", + akamaiFingerprintHash: "52d84b11737d980aef856699f885ca86", }, tls.HelloChrome_112_PSK.Str(): map[string]string{ ja3String: "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,45-51-17513-43-0-11-5-23-16-10-65281-27-18-35-13-21-41,29-23-24,0", ja3Hash: "11d372983aac706304b678a44351c8dd", - akamaiFingerprint: "1:65536,2:0,3:1000,4:6291456,6:262144|15663105|0|m,a,s,p", - akamaiFingerprintHash: "46cedabdca2073198a42fa10ca4494d0", + akamaiFingerprint: "1:65536;2:0;3:1000;4:6291456;6:262144|15663105|0|m,a,s,p", + akamaiFingerprintHash: "a345a694846ad9f6c97bcc3c75adbe26", }, tls.HelloChrome_112.Str(): map[string]string{ ja3String: "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,45-51-17513-43-0-11-5-23-16-10-65281-27-18-35-13-21,29-23-24,0", ja3Hash: "7f052aeccc9b50e9b3a43a02780539b2", - akamaiFingerprint: "1:65536,2:0,3:1000,4:6291456,6:262144|15663105|0|m,a,s,p", - akamaiFingerprintHash: "46cedabdca2073198a42fa10ca4494d0", + akamaiFingerprint: "1:65536;2:0;3:1000;4:6291456;6:262144|15663105|0|m,a,s,p", + akamaiFingerprintHash: "a345a694846ad9f6c97bcc3c75adbe26", }, tls.HelloChrome_111.Str(): map[string]string{ ja3String: "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,27-11-17513-5-10-18-23-0-45-51-43-35-65281-16-13-21,29-23-24,0", ja3Hash: "499d7c2439dc2fb83d1ab2e52b9dc680", - akamaiFingerprint: "1:65536,2:0,3:1000,4:6291456,6:262144|15663105|0|m,a,s,p", - akamaiFingerprintHash: "46cedabdca2073198a42fa10ca4494d0", + akamaiFingerprint: "1:65536;2:0;3:1000;4:6291456;6:262144|15663105|0|m,a,s,p", + akamaiFingerprintHash: "a345a694846ad9f6c97bcc3c75adbe26", }, tls.HelloChrome_110.Str(): map[string]string{ ja3String: "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,23-27-18-51-17513-0-16-35-11-5-65281-43-13-45-10-21,29-23-24,0", ja3Hash: "f30e7d05622c38802b2ee65d147f4df8", - akamaiFingerprint: "1:65536,2:0,3:1000,4:6291456,6:262144|15663105|0|m,a,s,p", - akamaiFingerprintHash: "46cedabdca2073198a42fa10ca4494d0", + akamaiFingerprint: "1:65536;2:0;3:1000;4:6291456;6:262144|15663105|0|m,a,s,p", + akamaiFingerprintHash: "a345a694846ad9f6c97bcc3c75adbe26", }, tls.HelloChrome_109.Str(): map[string]string{ ja3String: "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-21,29-23-24,0", ja3Hash: "cd08e31494f9531f560d64c695473da9", - akamaiFingerprint: "1:65536,2:0,3:1000,4:6291456,6:262144|15663105|0|m,a,s,p", - akamaiFingerprintHash: "46cedabdca2073198a42fa10ca4494d0", + akamaiFingerprint: "1:65536;2:0;3:1000;4:6291456;6:262144|15663105|0|m,a,s,p", + akamaiFingerprintHash: "a345a694846ad9f6c97bcc3c75adbe26", }, tls.HelloChrome_108.Str(): map[string]string{ ja3String: "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-21,29-23-24,0", ja3Hash: "cd08e31494f9531f560d64c695473da9", - akamaiFingerprint: "1:65536,2:0,3:1000,4:6291456,6:262144|15663105|0|m,a,s,p", - akamaiFingerprintHash: "46cedabdca2073198a42fa10ca4494d0", + akamaiFingerprint: "1:65536;2:0;3:1000;4:6291456;6:262144|15663105|0|m,a,s,p", + akamaiFingerprintHash: "a345a694846ad9f6c97bcc3c75adbe26", }, tls.HelloChrome_107.Str(): map[string]string{ ja3String: "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-21,29-23-24,0", ja3Hash: "cd08e31494f9531f560d64c695473da9", - akamaiFingerprint: "1:65536,2:0,3:1000,4:6291456,6:262144|15663105|0|m,a,s,p", - akamaiFingerprintHash: "46cedabdca2073198a42fa10ca4494d0", + akamaiFingerprint: "1:65536;2:0;3:1000;4:6291456;6:262144|15663105|0|m,a,s,p", + akamaiFingerprintHash: "a345a694846ad9f6c97bcc3c75adbe26", }, tls.HelloChrome_106.Str(): map[string]string{ ja3String: "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-21,29-23-24,0", ja3Hash: "cd08e31494f9531f560d64c695473da9", - akamaiFingerprint: "1:65536,2:0,3:1000,4:6291456,6:262144|15663105|0|m,a,s,p", - akamaiFingerprintHash: "46cedabdca2073198a42fa10ca4494d0", + akamaiFingerprint: "1:65536;2:0;3:1000;4:6291456;6:262144|15663105|0|m,a,s,p", + akamaiFingerprintHash: "a345a694846ad9f6c97bcc3c75adbe26", }, tls.HelloChrome_105.Str(): map[string]string{ ja3String: "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-21,29-23-24,0", ja3Hash: "cd08e31494f9531f560d64c695473da9", - akamaiFingerprint: "1:65536,3:1000,4:6291456,6:262144|15663105|0|m,a,s,p", - akamaiFingerprintHash: "7ad845f20fc17cc8088a0d9312b17da1", + akamaiFingerprint: "1:65536;3:1000;4:6291456;6:262144|15663105|0|m,a,s,p", + akamaiFingerprintHash: "4f04edce68a7ecbe689edce7bf5f23f3", }, tls.HelloChrome_104.Str(): map[string]string{ ja3String: "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-21,29-23-24,0", ja3Hash: "cd08e31494f9531f560d64c695473da9", - akamaiFingerprint: "1:65536,3:1000,4:6291456,6:262144|15663105|0|m,a,s,p", - akamaiFingerprintHash: "7ad845f20fc17cc8088a0d9312b17da1", + akamaiFingerprint: "1:65536;3:1000;4:6291456;6:262144|15663105|0|m,a,s,p", + akamaiFingerprintHash: "4f04edce68a7ecbe689edce7bf5f23f3", }, tls.HelloChrome_103.Str(): map[string]string{ ja3String: "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-21,29-23-24,0", ja3Hash: "cd08e31494f9531f560d64c695473da9", - akamaiFingerprint: "1:65536,3:1000,4:6291456,6:262144|15663105|0|m,a,s,p", - akamaiFingerprintHash: "7ad845f20fc17cc8088a0d9312b17da1", + akamaiFingerprint: "1:65536;3:1000;4:6291456;6:262144|15663105|0|m,a,s,p", + akamaiFingerprintHash: "4f04edce68a7ecbe689edce7bf5f23f3", }, }, firefox: { tls.HelloFirefox_102.Str(): map[string]string{ ja3String: "771,4865-4867-4866-49195-49199-52393-52392-49196-49200-49162-49161-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-34-51-43-13-45-28-21,29-23-24-25-256-257,0", ja3Hash: "579ccef312d18482fc42e2b822ca2430", - akamaiFingerprint: "1:65536,4:131072,5:16384|12517377|3:0:0:201,5:0:0:101,7:0:0:1,9:0:7:1,11:0:3:1,13:0:0:241|m,p,a,s", - akamaiFingerprintHash: "fd4f649c50a64e33cc9e2407055bafbe", + akamaiFingerprint: "1:65536;4:131072;5:16384|12517377|3:0:0:201,5:0:0:101,7:0:0:1,9:0:7:1,11:0:3:1,13:0:0:241|m,p,a,s", + akamaiFingerprintHash: "3d9132023bf26a71d40fe766e5c24c9d", }, tls.HelloFirefox_104.Str(): map[string]string{ ja3String: "771,4865-4867-4866-49195-49199-52393-52392-49196-49200-49162-49161-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-34-51-43-13-45-28-21,29-23-24-25-256-257,0", ja3Hash: "579ccef312d18482fc42e2b822ca2430", - akamaiFingerprint: "1:65536,4:131072,5:16384|12517377|3:0:0:201,5:0:0:101,7:0:0:1,9:0:7:1,11:0:3:1,13:0:0:241|m,p,a,s", - akamaiFingerprintHash: "fd4f649c50a64e33cc9e2407055bafbe", + akamaiFingerprint: "1:65536;4:131072;5:16384|12517377|3:0:0:201,5:0:0:101,7:0:0:1,9:0:7:1,11:0:3:1,13:0:0:241|m,p,a,s", + akamaiFingerprintHash: "3d9132023bf26a71d40fe766e5c24c9d", }, tls.HelloFirefox_105.Str(): map[string]string{ ja3String: "771,4865-4867-4866-49195-49199-52393-52392-49196-49200-49162-49161-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-34-51-43-13-45-28-21,29-23-24-25-256-257,0", ja3Hash: "579ccef312d18482fc42e2b822ca2430", - akamaiFingerprint: "1:65536,4:131072,5:16384|12517377|3:0:0:201,5:0:0:101,7:0:0:1,9:0:7:1,11:0:3:1,13:0:0:241|m,p,a,s", - akamaiFingerprintHash: "fd4f649c50a64e33cc9e2407055bafbe", + akamaiFingerprint: "1:65536;4:131072;5:16384|12517377|3:0:0:201,5:0:0:101,7:0:0:1,9:0:7:1,11:0:3:1,13:0:0:241|m,p,a,s", + akamaiFingerprintHash: "3d9132023bf26a71d40fe766e5c24c9d", }, tls.HelloFirefox_106.Str(): map[string]string{ ja3String: "771,4865-4867-4866-49195-49199-52393-52392-49196-49200-49162-49161-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-34-51-43-13-45-28-21,29-23-24-25-256-257,0", ja3Hash: "579ccef312d18482fc42e2b822ca2430", - akamaiFingerprint: "1:65536,4:131072,5:16384|12517377|3:0:0:201,5:0:0:101,7:0:0:1,9:0:7:1,11:0:3:1,13:0:0:241|m,p,a,s", - akamaiFingerprintHash: "fd4f649c50a64e33cc9e2407055bafbe", + akamaiFingerprint: "1:65536;4:131072;5:16384|12517377|3:0:0:201,5:0:0:101,7:0:0:1,9:0:7:1,11:0:3:1,13:0:0:241|m,p,a,s", + akamaiFingerprintHash: "3d9132023bf26a71d40fe766e5c24c9d", }, tls.HelloFirefox_108.Str(): map[string]string{ ja3String: "771,4865-4867-4866-49195-49199-52393-52392-49196-49200-49162-49161-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-34-51-43-13-45-28-21,29-23-24-25-256-257,0", ja3Hash: "579ccef312d18482fc42e2b822ca2430", - akamaiFingerprint: "1:65536,4:131072,5:16384|12517377|3:0:0:201,5:0:0:101,7:0:0:1,9:0:7:1,11:0:3:1,13:0:0:241|m,p,a,s", - akamaiFingerprintHash: "fd4f649c50a64e33cc9e2407055bafbe", + akamaiFingerprint: "1:65536;4:131072;5:16384|12517377|3:0:0:201,5:0:0:101,7:0:0:1,9:0:7:1,11:0:3:1,13:0:0:241|m,p,a,s", + akamaiFingerprintHash: "3d9132023bf26a71d40fe766e5c24c9d", }, tls.HelloFirefox_110.Str(): map[string]string{ ja3String: "771,4865-4867-4866-49195-49199-52393-52392-49196-49200-49162-49161-49171-49172-156-157-47-53,0-23-65281-10-11-16-5-34-51-43-13-28-21,29-23-24-25-256-257,0", ja3Hash: "ad55557b7cbd735c2627f7ebb3b3d493", - akamaiFingerprint: "1:65536,4:131072,5:16384|12517377|3:0:0:201,5:0:0:101,7:0:0:1,9:0:7:1,11:0:3:1,13:0:0:241|m,p,a,s", - akamaiFingerprintHash: "fd4f649c50a64e33cc9e2407055bafbe", + akamaiFingerprint: "1:65536;4:131072;5:16384|12517377|3:0:0:201,5:0:0:101,7:0:0:1,9:0:7:1,11:0:3:1,13:0:0:241|m,p,a,s", + akamaiFingerprintHash: "3d9132023bf26a71d40fe766e5c24c9d", }, profiles.Firefox_117.GetClientHelloStr(): map[string]string{ ja3String: "771,4865-4867-4866-49195-49199-52393-52392-49196-49200-49162-49161-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-34-51-43-13-45-28-21,29-23-24-25-256-257,0", ja3Hash: "579ccef312d18482fc42e2b822ca2430", - akamaiFingerprint: "1:65536,4:131072,5:16384|12517377|3:0:0:201,5:0:0:101,7:0:0:1,9:0:7:1,11:0:3:1,13:0:0:241|m,p,a,s", - akamaiFingerprintHash: "fd4f649c50a64e33cc9e2407055bafbe", + akamaiFingerprint: "1:65536;4:131072;5:16384|12517377|3:0:0:201,5:0:0:101,7:0:0:1,9:0:7:1,11:0:3:1,13:0:0:241|m,p,a,s", + akamaiFingerprintHash: "3d9132023bf26a71d40fe766e5c24c9d", }, }, opera: { tls.HelloOpera_89.Str(): map[string]string{ ja3String: "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-21,29-23-24,0", ja3Hash: "cd08e31494f9531f560d64c695473da9", - akamaiFingerprint: "1:65536,3:1000,4:6291456,6:262144|15663105|0|m,a,s,p", - akamaiFingerprintHash: "7ad845f20fc17cc8088a0d9312b17da1", + akamaiFingerprint: "1:65536;3:1000;4:6291456;6:262144|15663105|0|m,a,s,p", + akamaiFingerprintHash: "4f04edce68a7ecbe689edce7bf5f23f3", }, tls.HelloOpera_90.Str(): map[string]string{ ja3String: "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-21,29-23-24,0", ja3Hash: "cd08e31494f9531f560d64c695473da9", - akamaiFingerprint: "1:65536,3:1000,4:6291456,6:262144|15663105|0|m,a,s,p", - akamaiFingerprintHash: "7ad845f20fc17cc8088a0d9312b17da1", + akamaiFingerprint: "1:65536;3:1000;4:6291456;6:262144|15663105|0|m,a,s,p", + akamaiFingerprintHash: "4f04edce68a7ecbe689edce7bf5f23f3", }, tls.HelloOpera_91.Str(): map[string]string{ ja3String: "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-21,29-23-24,0", ja3Hash: "cd08e31494f9531f560d64c695473da9", - akamaiFingerprint: "1:65536,3:1000,4:6291456,6:262144|15663105|0|m,a,s,p", - akamaiFingerprintHash: "7ad845f20fc17cc8088a0d9312b17da1", + akamaiFingerprint: "1:65536;3:1000;4:6291456;6:262144|15663105|0|m,a,s,p", + akamaiFingerprintHash: "4f04edce68a7ecbe689edce7bf5f23f3", }, }, safari: { tls.HelloSafari_15_6_1.Str(): map[string]string{ ja3String: "771,4865-4866-4867-49196-49195-52393-49200-49199-52392-49162-49161-49172-49171-157-156-53-47-49160-49170-10,0-23-65281-10-11-16-5-13-18-51-45-43-27-21,29-23-24-25,0", ja3Hash: "773906b0efdefa24a7f2b8eb6985bf37", - akamaiFingerprint: "4:4194304,3:100|10485760|0|m,s,p,a", - akamaiFingerprintHash: "e7b6dfd2eca81022e22f49765591e8c3", + akamaiFingerprint: "4:4194304;3:100|10485760|0|m,s,p,a", + akamaiFingerprintHash: "dda308d35f4e5db7b52a61720ca1b122", }, tls.HelloSafari_16_0.Str(): map[string]string{ ja3String: "771,4865-4866-4867-49196-49195-52393-49200-49199-52392-49162-49161-49172-49171-157-156-53-47-49160-49170-10,0-23-65281-10-11-16-5-13-18-51-45-43-27-21,29-23-24-25,0", ja3Hash: "773906b0efdefa24a7f2b8eb6985bf37", - akamaiFingerprint: "4:4194304,3:100|10485760|0|m,s,p,a", - akamaiFingerprintHash: "e7b6dfd2eca81022e22f49765591e8c3", + akamaiFingerprint: "4:4194304;3:100|10485760|0|m,s,p,a", + akamaiFingerprintHash: "dda308d35f4e5db7b52a61720ca1b122", }, }, safariIpadOs: { tls.HelloIPad_15_6.Str(): map[string]string{ ja3String: "771,4865-4866-4867-49196-49195-52393-49200-49199-52392-49162-49161-49172-49171-157-156-53-47-49160-49170-10,0-23-65281-10-11-16-5-13-18-51-45-43-27-21,29-23-24-25,0", ja3Hash: "773906b0efdefa24a7f2b8eb6985bf37", - akamaiFingerprint: "4:2097152,3:100|10485760|0|m,s,p,a", - akamaiFingerprintHash: "8fe3e4ae51fb38d5c5108eabbf2a123c", + akamaiFingerprint: "4:2097152;3:100|10485760|0|m,s,p,a", + akamaiFingerprintHash: "d5fcbdc393757341115a861bf8d23265", }, }, safariIos: { tls.HelloIOS_15_5.Str(): map[string]string{ ja3String: "771,4865-4866-4867-49196-49195-52393-49200-49199-52392-49162-49161-49172-49171-157-156-53-47-49160-49170-10,0-23-65281-10-11-16-5-13-18-51-45-43-27-21,29-23-24-25,0", ja3Hash: "773906b0efdefa24a7f2b8eb6985bf37", - akamaiFingerprint: "4:2097152,3:100|10485760|0|m,s,p,a", - akamaiFingerprintHash: "8fe3e4ae51fb38d5c5108eabbf2a123c", + akamaiFingerprint: "4:2097152;3:100|10485760|0|m,s,p,a", + akamaiFingerprintHash: "d5fcbdc393757341115a861bf8d23265", }, tls.HelloIOS_15_6.Str(): map[string]string{ ja3String: "771,4865-4866-4867-49196-49195-52393-49200-49199-52392-49162-49161-49172-49171-157-156-53-47-49160-49170-10,0-23-65281-10-11-16-5-13-18-51-45-43-27-21,29-23-24-25,0", ja3Hash: "773906b0efdefa24a7f2b8eb6985bf37", - akamaiFingerprint: "4:2097152,3:100|10485760|0|m,s,p,a", - akamaiFingerprintHash: "8fe3e4ae51fb38d5c5108eabbf2a123c", + akamaiFingerprint: "4:2097152;3:100|10485760|0|m,s,p,a", + akamaiFingerprintHash: "d5fcbdc393757341115a861bf8d23265", }, tls.HelloIOS_16_0.Str(): map[string]string{ ja3String: "771,4865-4866-4867-49196-49195-52393-49200-49199-52392-49162-49161-49172-49171-157-156-53-47-49160-49170-10,0-23-65281-10-11-16-5-13-18-51-45-43-27-21,29-23-24-25,0", ja3Hash: "773906b0efdefa24a7f2b8eb6985bf37", - akamaiFingerprint: "4:2097152,3:100|10485760|0|m,s,p,a", - akamaiFingerprintHash: "8fe3e4ae51fb38d5c5108eabbf2a123c", + akamaiFingerprint: "4:2097152;3:100|10485760|0|m,s,p,a", + akamaiFingerprintHash: "d5fcbdc393757341115a861bf8d23265", }, profiles.Safari_IOS_17_0.GetClientHelloStr(): map[string]string{ ja3String: "771,4865-4866-4867-49196-49195-52393-49200-49199-52392-49162-49161-49172-49171-157-156-53-47-49160-49170-10,0-23-65281-10-11-16-5-13-18-51-45-43-27-21,29-23-24-25,0", ja3Hash: "773906b0efdefa24a7f2b8eb6985bf37", - akamaiFingerprint: "2:0,4:2097152,3:100|10485760|0|m,s,p,a", - akamaiFingerprintHash: "44e2112c513fdb93cd12e6ccd1b9dce5", + akamaiFingerprint: "2:0;4:2097152;3:100|10485760|0|m,s,p,a", + akamaiFingerprintHash: "ad8424af1cc590e09f7b0c499bf7fcdb", }, profiles.Safari_IOS_18_0.GetClientHelloStr(): map[string]string{ ja3String: "771,4865-4866-4867-49196-49195-52393-49200-49199-52392-49162-49161-49172-49171-157-156-53-47-49160-49170-10,0-23-65281-10-11-16-5-13-18-51-45-43-27-21,29-23-24-25,0", ja3Hash: "773906b0efdefa24a7f2b8eb6985bf37", - akamaiFingerprint: "2:0,3:100,4:2097152,:1,:1|10420225|0|m,s,a,p", - akamaiFingerprintHash: "3899baa52d09f55b52580eb6d755ce5c", + akamaiFingerprint: "2:0;3:100;4:2097152;:1;9:1|10420225|0|m,s,a,p", + akamaiFingerprintHash: "62317f06028f316631c157c720223e43", }, }, okhttpAndroid: {