-
-
Save xkdvSrPD/1558e37031e5ca970200900bd22ace53 to your computer and use it in GitHub Desktop.
golang utls fingerprint
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // to start the project: | |
| // go mod init | |
| // go get -u github.com/imroc/req/v3 | |
| // 在Xray中,使用vsion且设置TLs指纹为safari时,对其JA4指纹sha512后,后六位是 | |
| package main | |
| import ( | |
| "crypto/sha512" | |
| "encoding/hex" | |
| "encoding/json" | |
| "flag" | |
| "fmt" | |
| "io/ioutil" | |
| "os" | |
| "github.com/imroc/req/v3" | |
| tls "github.com/refraction-networking/utls" | |
| ) | |
| func main() { | |
| // Define a command-line argument to accept the desired fingerprint | |
| fingerprintArg := flag.String("fingerprint", "chrome", "Specify the fingerprint (e.g., chrome, edge, firefox, safari)") | |
| flag.Parse() | |
| // Map of fingerprints to their corresponding utls ClientHelloID | |
| fingerprintMap := map[string]tls.ClientHelloID{ | |
| "chrome": tls.HelloChrome_115_PQ, | |
| "edge": tls.HelloEdge_106, | |
| "firefox": tls.HelloFirefox_105, | |
| "safari": tls.HelloSafari_16_0, | |
| "ios": tls.HelloIOS_14, | |
| } | |
| // Match the provided argument to a fingerprint | |
| fingerprintID, exists := fingerprintMap[*fingerprintArg] | |
| if !exists { | |
| fmt.Fprintf(os.Stderr, "Invalid fingerprint: %s\n", *fingerprintArg) | |
| fmt.Fprintf(os.Stderr, "Available fingerprints: chrome, edge, firefox, safari\n") | |
| os.Exit(1) | |
| } | |
| // Create the HTTP client with the specified fingerprint | |
| client := req.C(). | |
| SetUserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"). | |
| SetTLSFingerprint(fingerprintID) | |
| // Make a GET request | |
| res, err := client.R().Get("https://tls.peet.ws/api/all") | |
| if err != nil { | |
| fmt.Printf("Request failed: %v\n", err) | |
| os.Exit(1) | |
| } | |
| // Print the response | |
| fmt.Println(res) | |
| // Read the response body into a string | |
| responseBody, err := ioutil.ReadAll(res.Body) | |
| if err != nil { | |
| fmt.Printf("Failed to read response body: %v\n", err) | |
| os.Exit(1) | |
| } | |
| defer res.Body.Close() // Close the response body after reading | |
| // Convert the response body to a string | |
| responseBodyStr := string(responseBody) | |
| // Extract the JA4 fingerprint | |
| ja4, err := extractJA4Fingerprint(responseBodyStr) | |
| if err != nil { | |
| fmt.Printf("Failed to extract JA4 fingerprint: %v\n", err) | |
| os.Exit(1) | |
| } | |
| // Compute the SHA-512 hash of the JA4 fingerprint | |
| sha512Hash := computeSHA512(ja4) | |
| // Output the results | |
| fmt.Printf("JA4 Fingerprint: %s\n", ja4) | |
| fmt.Printf("SHA-512 Hash: %s\n", sha512Hash) | |
| fmt.Printf("Last Six Characters: %s\n", getLastSixCharacters(sha512Hash)) | |
| } | |
| // extractJA4Fingerprint extracts the JA4 fingerprint from the response body | |
| func extractJA4Fingerprint(responseBody string) (string, error) { | |
| // Parse the response body as JSON | |
| var result map[string]interface{} | |
| if err := json.Unmarshal([]byte(responseBody), &result); err != nil { | |
| return "", fmt.Errorf("failed to parse JSON response: %v", err) | |
| } | |
| // Extract the TLS section | |
| tlsData, ok := result["tls"].(map[string]interface{}) | |
| if !ok { | |
| return "", fmt.Errorf("no TLS data found in the response") | |
| } | |
| // Extract the ja4 field | |
| ja4, ok := tlsData["ja4"].(string) | |
| if !ok { | |
| return "", fmt.Errorf("no ja4 field found in the TLS data") | |
| } | |
| return ja4, nil | |
| } | |
| // computeSHA512 computes the SHA-512 hash of a given string | |
| func computeSHA512(input string) string { | |
| hasher := sha512.New() | |
| hasher.Write([]byte(input)) | |
| hashBytes := hasher.Sum(nil) | |
| return hex.EncodeToString(hashBytes) | |
| } | |
| // getLastSixCharacters returns the last six characters of a string | |
| func getLastSixCharacters(input string) string { | |
| if len(input) < 6 { | |
| return input | |
| } | |
| return input[len(input)-6:] | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment