ja4plus

package module
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Apr 4, 2025 License: MIT Imports: 10 Imported by: 0

README

JA4Plus

JA4Plus is a go library for generating ja4+ fingerprints.

Overview

JA4Plus currently offers a single fingerprinting function:

Contributions are welcome for the other fingerprints in the family 😉

Omission of JA4H

The JA4H hash, based on properties of the HTTP request, cannot currently be easily implemented in go, since it requires headers to be observed in the order sent by the client. See e.g.: https://go.dev/issue/24375

Examples

For example usage, checkou out examples_test.go.

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func JA4

func JA4(hello *tls.ClientHelloInfo) string

JA4 generates a JA4 fingerprint from the given tls.ClientHelloInfo. It extracts TLS Version, Cipher Suites, Extensions, and ALPN Protocols.

Example
package main

import (
	"crypto/tls"
	"fmt"
	"log"
	"net/http"
	"net/http/httptest"

	"github.com/exaring/ja4plus"
)

func main() {
	srv := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
	defer srv.Close()

	srv.TLS = &tls.Config{
		GetConfigForClient: func(hello *tls.ClientHelloInfo) (*tls.Config, error) {
			fmt.Println(ja4plus.JA4(hello))
			return nil, nil
		},
	}
	srv.EnableHTTP2 = true
	srv.StartTLS()
	client := srv.Client()

	resp, err := client.Get(srv.URL)
	if err != nil {
		log.Println(err)
		return
	}
	defer resp.Body.Close()
}
Output:

t13i1310h2_f57a46bbacb6_e7c285222651

func JA4FromContext

func JA4FromContext(ctx context.Context) string

JA4FromContext extracts the JA4 fingerprint from the provided http.Request.Context. It requires a server set up with JA4Middleware to work.

Types

type JA4Middleware

type JA4Middleware struct {
	// contains filtered or unexported fields
}

JA4Middleware is a helper to plug the JA4 fingerprinting into your HTTP server. It only exists because there is no direct way to pass information from the TLS handshake to the HTTP handler. Usage:

ja4middleware := ja4plus.JA4Middleware{}
srv := http.Server{
	Handler: ja4middleware.Wrap(...),
	TLSConfig: &tls.Config{
		GetConfigForClient: func(chi *tls.ClientHelloInfo) (*tls.Config, error) {
			ja4middleware.StoreFingerprintFromClientHello(chi)
			return nil, nil
		},
	},
	ConnState: ja4middleware.ConnStateCallback,
}
srv.ListenAndServeTLS("cert.pem", "key.pem")

Afterwards the fingerprint can be accessed via [JA4Middleware.FingerprintFromContext]

Example
package main

import (
	"crypto/tls"
	"io"
	"net/http"

	"github.com/exaring/ja4plus"
)

func main() {
	exampleHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		_, _ = io.WriteString(w, ja4plus.JA4FromContext(r.Context()))
	})

	ja4middleware := ja4plus.JA4Middleware{}

	/* srv */
	_ = http.Server{
		Addr:    ":8080",
		Handler: ja4middleware.Wrap(exampleHandler),
		TLSConfig: &tls.Config{
			GetConfigForClient: func(chi *tls.ClientHelloInfo) (*tls.Config, error) {
				ja4middleware.StoreFingerprintFromClientHello(chi)
				return nil, nil
			},
		},
		ConnState: ja4middleware.ConnStateCallback,
	}

	// srv.ListenAndServeTLS(...)
}
Output:

func (*JA4Middleware) ConnStateCallback

func (m *JA4Middleware) ConnStateCallback(conn net.Conn, state http.ConnState)

ConnStateCallback is a callback that should be set as the http.Server's ConnState to clean up the fingerprint cache.

func (*JA4Middleware) StoreFingerprintFromClientHello

func (m *JA4Middleware) StoreFingerprintFromClientHello(hello *tls.ClientHelloInfo)

StoreFingerprintFromClientHello stores the JA4 fingerprint of the provided tls.ClientHelloInfo in the middleware.

func (*JA4Middleware) Wrap

func (m *JA4Middleware) Wrap(next http.Handler) http.Handler

Wrap wraps the provided http.Handler and injects the JA4 fingerprint into the http.Request.Context. It requires a server set up with JA4Middleware to work.

Jump to

Keyboard shortcuts

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