ja4plus 0.2.0__tar.gz → 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. ja4plus-0.3.0/.github/workflows/publish.yml +32 -0
  2. ja4plus-0.3.0/.github/workflows/test.yml +43 -0
  3. ja4plus-0.3.0/.gitignore +12 -0
  4. {ja4plus-0.2.0 → ja4plus-0.3.0}/LICENSE +28 -0
  5. {ja4plus-0.2.0/ja4plus.egg-info → ja4plus-0.3.0}/PKG-INFO +32 -6
  6. {ja4plus-0.2.0 → ja4plus-0.3.0}/README.md +27 -0
  7. ja4plus-0.3.0/docs/README.md +19 -0
  8. ja4plus-0.3.0/docs/api_reference.md +171 -0
  9. ja4plus-0.3.0/docs/usage.md +308 -0
  10. ja4plus-0.3.0/examples/demo_fingerprints.py +454 -0
  11. ja4plus-0.3.0/examples/live_traffic_fingerprinting.py +129 -0
  12. ja4plus-0.3.0/examples/monitoring_daemon.py +272 -0
  13. ja4plus-0.3.0/examples/pcap_analysis.py +68 -0
  14. ja4plus-0.3.0/examples/tcpdump_workflows.py +348 -0
  15. ja4plus-0.3.0/examples/threat_detection.py +86 -0
  16. {ja4plus-0.2.0 → ja4plus-0.3.0}/ja4plus/__init__.py +1 -1
  17. ja4plus-0.3.0/ja4plus/cli.py +364 -0
  18. {ja4plus-0.2.0 → ja4plus-0.3.0}/ja4plus/collector.py +12 -2
  19. ja4plus-0.3.0/ja4plus/data/ja4plus-mapping.csv +67 -0
  20. {ja4plus-0.2.0 → ja4plus-0.3.0}/ja4plus/fingerprinters/base.py +5 -0
  21. {ja4plus-0.2.0 → ja4plus-0.3.0}/ja4plus/fingerprinters/ja4.py +7 -2
  22. {ja4plus-0.2.0 → ja4plus-0.3.0}/ja4plus/fingerprinters/ja4h.py +5 -1
  23. {ja4plus-0.2.0 → ja4plus-0.3.0}/ja4plus/fingerprinters/ja4l.py +5 -1
  24. {ja4plus-0.2.0 → ja4plus-0.3.0}/ja4plus/fingerprinters/ja4s.py +5 -1
  25. {ja4plus-0.2.0 → ja4plus-0.3.0}/ja4plus/fingerprinters/ja4ssh.py +3 -0
  26. {ja4plus-0.2.0 → ja4plus-0.3.0}/ja4plus/fingerprinters/ja4t.py +6 -2
  27. {ja4plus-0.2.0 → ja4plus-0.3.0}/ja4plus/fingerprinters/ja4ts.py +6 -2
  28. {ja4plus-0.2.0 → ja4plus-0.3.0}/ja4plus/fingerprinters/ja4x.py +17 -12
  29. ja4plus-0.3.0/ja4plus/ja4db.py +140 -0
  30. {ja4plus-0.2.0 → ja4plus-0.3.0}/ja4plus/utils/http_utils.py +7 -2
  31. {ja4plus-0.2.0 → ja4plus-0.3.0}/ja4plus/utils/ssh_utils.py +11 -7
  32. {ja4plus-0.2.0 → ja4plus-0.3.0}/ja4plus/utils/tls_utils.py +13 -8
  33. {ja4plus-0.2.0 → ja4plus-0.3.0}/ja4plus/utils/x509_utils.py +9 -52
  34. {ja4plus-0.2.0 → ja4plus-0.3.0/ja4plus.egg-info}/PKG-INFO +32 -6
  35. {ja4plus-0.2.0 → ja4plus-0.3.0}/ja4plus.egg-info/SOURCES.txt +29 -3
  36. ja4plus-0.3.0/ja4plus.egg-info/entry_points.txt +2 -0
  37. {ja4plus-0.2.0 → ja4plus-0.3.0}/ja4plus.egg-info/requires.txt +4 -1
  38. {ja4plus-0.2.0 → ja4plus-0.3.0}/pyproject.toml +18 -4
  39. {ja4plus-0.2.0 → ja4plus-0.3.0}/requirements.txt +1 -1
  40. ja4plus-0.3.0/tests/__init__.py +0 -0
  41. ja4plus-0.3.0/tests/data/dns.cap +0 -0
  42. ja4plus-0.3.0/tests/data/example_cert.der +0 -0
  43. ja4plus-0.3.0/tests/data/filedownload.dmp +0 -0
  44. ja4plus-0.3.0/tests/data/http.cap +0 -0
  45. ja4plus-0.3.0/tests/data/suspectemployeechat.dmp +0 -0
  46. ja4plus-0.3.0/tests/data/test_cert.der +0 -0
  47. ja4plus-0.3.0/tests/data/wrongdissector.dmp +0 -0
  48. ja4plus-0.3.0/tests/download_test_vectors.py +51 -0
  49. ja4plus-0.3.0/tests/test_cli.py +159 -0
  50. {ja4plus-0.2.0 → ja4plus-0.3.0}/tests/test_comprehensive.py +2 -2
  51. ja4plus-0.3.0/tests/test_ja4db.py +123 -0
  52. {ja4plus-0.2.0 → ja4plus-0.3.0}/tests/test_ja4x.py +1 -1
  53. {ja4plus-0.2.0 → ja4plus-0.3.0}/tests/test_ja4x_deep.py +1 -1
  54. ja4plus-0.3.0/tests/test_spec_validation.py +252 -0
  55. ja4plus-0.2.0/MANIFEST.in +0 -3
  56. ja4plus-0.2.0/setup.py +0 -52
  57. {ja4plus-0.2.0 → ja4plus-0.3.0}/ja4plus/fingerprinters/__init__.py +0 -0
  58. {ja4plus-0.2.0 → ja4plus-0.3.0}/ja4plus/utils/__init__.py +0 -0
  59. {ja4plus-0.2.0 → ja4plus-0.3.0}/ja4plus.egg-info/dependency_links.txt +0 -0
  60. {ja4plus-0.2.0 → ja4plus-0.3.0}/ja4plus.egg-info/top_level.txt +0 -0
  61. {ja4plus-0.2.0 → ja4plus-0.3.0}/setup.cfg +0 -0
  62. {ja4plus-0.2.0 → ja4plus-0.3.0}/tests/test_edge_cases.py +0 -0
  63. {ja4plus-0.2.0 → ja4plus-0.3.0}/tests/test_integration.py +0 -0
  64. {ja4plus-0.2.0 → ja4plus-0.3.0}/tests/test_ja4.py +0 -0
  65. {ja4plus-0.2.0 → ja4plus-0.3.0}/tests/test_ja4_deep.py +0 -0
  66. {ja4plus-0.2.0 → ja4plus-0.3.0}/tests/test_ja4h.py +0 -0
  67. {ja4plus-0.2.0 → ja4plus-0.3.0}/tests/test_ja4h_deep.py +0 -0
  68. {ja4plus-0.2.0 → ja4plus-0.3.0}/tests/test_ja4l.py +0 -0
  69. {ja4plus-0.2.0 → ja4plus-0.3.0}/tests/test_ja4s.py +0 -0
  70. {ja4plus-0.2.0 → ja4plus-0.3.0}/tests/test_ja4ssh.py +0 -0
  71. {ja4plus-0.2.0 → ja4plus-0.3.0}/tests/test_ja4ssh_deep.py +0 -0
  72. {ja4plus-0.2.0 → ja4plus-0.3.0}/tests/test_ja4t.py +0 -0
  73. {ja4plus-0.2.0 → ja4plus-0.3.0}/tests/test_ja4t_deep.py +0 -0
  74. {ja4plus-0.2.0 → ja4plus-0.3.0}/tests/test_ja4ts.py +0 -0
  75. {ja4plus-0.2.0 → ja4plus-0.3.0}/tests/test_utils.py +0 -0
@@ -0,0 +1,32 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ id-token: write
9
+
10
+ jobs:
11
+ publish:
12
+ runs-on: ubuntu-latest
13
+ environment: pypi
14
+
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+
18
+ - name: Set up Python
19
+ uses: actions/setup-python@v5
20
+ with:
21
+ python-version: "3.12"
22
+
23
+ - name: Install build tools
24
+ run: |
25
+ python -m pip install --upgrade pip
26
+ pip install build
27
+
28
+ - name: Build package
29
+ run: python -m build
30
+
31
+ - name: Publish to PyPI
32
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,43 @@
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ branches: [master]
6
+ pull_request:
7
+ branches: [master]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ${{ matrix.os }}
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ os: [ubuntu-latest]
16
+ python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
17
+ include:
18
+ - os: macos-latest
19
+ python-version: "3.12"
20
+
21
+ steps:
22
+ - uses: actions/checkout@v4
23
+
24
+ - name: Set up Python ${{ matrix.python-version }}
25
+ uses: actions/setup-python@v5
26
+ with:
27
+ python-version: ${{ matrix.python-version }}
28
+
29
+ - name: Install dependencies
30
+ run: |
31
+ python -m pip install --upgrade pip
32
+ pip install -e ".[dev]"
33
+
34
+ - name: Run tests
35
+ run: |
36
+ python -m pytest tests/ -v --tb=short --junitxml=test-results.xml
37
+
38
+ - name: Upload test results
39
+ if: always()
40
+ uses: actions/upload-artifact@v4
41
+ with:
42
+ name: test-results-${{ matrix.os }}-py${{ matrix.python-version }}
43
+ path: test-results.xml
@@ -0,0 +1,12 @@
1
+ # Downloaded FoxIO test vectors (not committed)
2
+ tests/foxio_vectors/
3
+
4
+ __pycache__/
5
+ *.py[cod]
6
+ *.egg-info/
7
+ dist/
8
+ build/
9
+ *.egg
10
+ .omc/
11
+ .claude/
12
+ .gstack/
@@ -26,3 +26,31 @@ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
26
  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
27
  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
28
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+
30
+ ---
31
+
32
+ DUAL-LICENSE NOTICE
33
+ ===================
34
+
35
+ This repository has a dual-license structure:
36
+
37
+ 1. The ja4plus library code (this repository) is licensed under the
38
+ BSD 3-Clause License above.
39
+
40
+ 2. The JA4+ fingerprinting specifications themselves were created by
41
+ FoxIO-LLC. The fingerprinting methods JA4S, JA4H, JA4T, JA4TS, JA4L,
42
+ JA4X, and JA4SSH are implementations of those specifications and are
43
+ subject to the FoxIO License 1.1.
44
+
45
+ JA4 (TLS Client Fingerprinting) is open source under BSD-3-Clause
46
+ per FoxIO's own licensing terms.
47
+
48
+ The FoxIO License 1.1 is permissive for most use cases, including:
49
+ - Academic and research use
50
+ - Internal business use
51
+ - Security research and tooling
52
+
53
+ Commercial productization or resale of JA4+ fingerprinting (other than
54
+ JA4 itself) may require a separate commercial license from FoxIO.
55
+
56
+ Full terms: https://github.com/FoxIO-LLC/ja4/blob/main/LICENSE
@@ -1,9 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ja4plus
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: JA4+ network fingerprinting library for TLS, TCP, HTTP, SSH, and X.509 analysis
5
- Home-page: https://github.com/Crank-Git/ja4plus
6
- License-Expression: BSD-3-Clause
5
+ License: BSD-3-Clause AND LicenseRef-FoxIO-1.1
7
6
  Project-URL: Homepage, https://github.com/Crank-Git/ja4plus
8
7
  Project-URL: Bug Tracker, https://github.com/Crank-Git/ja4plus/issues
9
8
  Project-URL: Source Code, https://github.com/Crank-Git/ja4plus
@@ -28,13 +27,17 @@ Requires-Python: >=3.8
28
27
  Description-Content-Type: text/markdown
29
28
  License-File: LICENSE
30
29
  Requires-Dist: scapy>=2.4.0
31
- Requires-Dist: cryptography>=3.4.0
30
+ Requires-Dist: cryptography>=42.0.0
32
31
  Provides-Extra: dev
33
32
  Requires-Dist: pytest>=7.0; extra == "dev"
34
33
  Requires-Dist: pytest-cov>=3.0; extra == "dev"
35
- Dynamic: home-page
34
+ Provides-Extra: lookup
35
+ Requires-Dist: requests>=2.20.0; extra == "lookup"
36
36
  Dynamic: license-file
37
- Dynamic: requires-python
37
+
38
+ [![Tests](https://github.com/Crank-Git/ja4plus/actions/workflows/test.yml/badge.svg)](https://github.com/Crank-Git/ja4plus/actions/workflows/test.yml)
39
+ [![PyPI version](https://badge.fury.io/py/ja4plus.svg)](https://pypi.org/project/ja4plus/)
40
+ [![Python versions](https://img.shields.io/pypi/pyversions/ja4plus.svg)](https://pypi.org/project/ja4plus/)
38
41
 
39
42
  # JA4+
40
43
 
@@ -69,6 +72,19 @@ cd ja4plus
69
72
  pip install -e .
70
73
  ```
71
74
 
75
+ ## Licensing
76
+
77
+ This library (ja4plus) is released under the **BSD 3-Clause License**.
78
+
79
+ The JA4+ fingerprinting specifications were created by [FoxIO](https://foxio.io):
80
+
81
+ - **JA4** (TLS Client Fingerprinting) is open source under **BSD-3-Clause** per FoxIO.
82
+ - **JA4S, JA4H, JA4T, JA4TS, JA4L, JA4X, JA4SSH** implement FoxIO's specifications and are subject to the **FoxIO License 1.1**.
83
+
84
+ The FoxIO License 1.1 is permissive for most use cases, including academic use, internal business use, and security research. Commercial productization or resale of these fingerprinting methods (other than JA4) may require a separate license from FoxIO.
85
+
86
+ See the [FoxIO License](https://github.com/FoxIO-LLC/ja4/blob/main/LICENSE) for full terms, and [LICENSE](LICENSE) in this repository for the complete dual-license notice.
87
+
72
88
  ## Quick Start
73
89
 
74
90
  ```python
@@ -169,6 +185,16 @@ pip install -e ".[dev]"
169
185
  pytest tests/ -v
170
186
  ```
171
187
 
188
+ ## Spec Validation
189
+
190
+ ja4plus is validated against [FoxIO's official test vectors](https://github.com/FoxIO-LLC/ja4).
191
+ Run the validation suite:
192
+
193
+ ```bash
194
+ python tests/download_test_vectors.py
195
+ pytest -m spec_validation -v
196
+ ```
197
+
172
198
  ## License
173
199
 
174
200
  BSD 3-Clause License. See [LICENSE](LICENSE) for details.
@@ -1,3 +1,7 @@
1
+ [![Tests](https://github.com/Crank-Git/ja4plus/actions/workflows/test.yml/badge.svg)](https://github.com/Crank-Git/ja4plus/actions/workflows/test.yml)
2
+ [![PyPI version](https://badge.fury.io/py/ja4plus.svg)](https://pypi.org/project/ja4plus/)
3
+ [![Python versions](https://img.shields.io/pypi/pyversions/ja4plus.svg)](https://pypi.org/project/ja4plus/)
4
+
1
5
  # JA4+
2
6
 
3
7
  A Python library for JA4+ network fingerprinting. Implements all eight JA4+ methods for identifying and classifying network traffic based on TLS, TCP, HTTP, SSH, and X.509 characteristics.
@@ -31,6 +35,19 @@ cd ja4plus
31
35
  pip install -e .
32
36
  ```
33
37
 
38
+ ## Licensing
39
+
40
+ This library (ja4plus) is released under the **BSD 3-Clause License**.
41
+
42
+ The JA4+ fingerprinting specifications were created by [FoxIO](https://foxio.io):
43
+
44
+ - **JA4** (TLS Client Fingerprinting) is open source under **BSD-3-Clause** per FoxIO.
45
+ - **JA4S, JA4H, JA4T, JA4TS, JA4L, JA4X, JA4SSH** implement FoxIO's specifications and are subject to the **FoxIO License 1.1**.
46
+
47
+ The FoxIO License 1.1 is permissive for most use cases, including academic use, internal business use, and security research. Commercial productization or resale of these fingerprinting methods (other than JA4) may require a separate license from FoxIO.
48
+
49
+ See the [FoxIO License](https://github.com/FoxIO-LLC/ja4/blob/main/LICENSE) for full terms, and [LICENSE](LICENSE) in this repository for the complete dual-license notice.
50
+
34
51
  ## Quick Start
35
52
 
36
53
  ```python
@@ -131,6 +148,16 @@ pip install -e ".[dev]"
131
148
  pytest tests/ -v
132
149
  ```
133
150
 
151
+ ## Spec Validation
152
+
153
+ ja4plus is validated against [FoxIO's official test vectors](https://github.com/FoxIO-LLC/ja4).
154
+ Run the validation suite:
155
+
156
+ ```bash
157
+ python tests/download_test_vectors.py
158
+ pytest -m spec_validation -v
159
+ ```
160
+
134
161
  ## License
135
162
 
136
163
  BSD 3-Clause License. See [LICENSE](LICENSE) for details.
@@ -0,0 +1,19 @@
1
+ # JA4+ Documentation
2
+
3
+ ## Contents
4
+
5
+ - [Usage Guide](usage.md) - Detailed usage for each fingerprinter with examples
6
+ - [API Reference](api_reference.md) - Classes, methods, and convenience functions
7
+
8
+ ## Quick Links
9
+
10
+ - [JA4 - TLS Client](usage.md#ja4---tls-client)
11
+ - [JA4S - TLS Server](usage.md#ja4s---tls-server)
12
+ - [JA4H - HTTP](usage.md#ja4h---http)
13
+ - [JA4T - TCP Client](usage.md#ja4t---tcp-client)
14
+ - [JA4TS - TCP Server](usage.md#ja4ts---tcp-server)
15
+ - [JA4L - Latency](usage.md#ja4l---latency)
16
+ - [JA4X - X.509 Certificate](usage.md#ja4x---x509-certificate)
17
+ - [JA4SSH - SSH](usage.md#ja4ssh---ssh)
18
+ - [PCAP Analysis](usage.md#pcap-analysis)
19
+ - [Live Capture](usage.md#live-capture)
@@ -0,0 +1,171 @@
1
+ # API Reference
2
+
3
+ ## Fingerprinter Classes
4
+
5
+ All fingerprinters inherit from `BaseFingerprinter` and share a common interface.
6
+
7
+ ### Common Methods
8
+
9
+ | Method | Returns | Description |
10
+ |--------|---------|-------------|
11
+ | `process_packet(packet)` | `str` or `None` | Process a scapy packet. Returns fingerprint string if one is generated. |
12
+ | `get_fingerprints()` | `list[dict]` | Returns all collected fingerprints as `{"fingerprint": str, ...}` dicts. |
13
+ | `reset()` | `None` | Clears all collected fingerprints and internal state. |
14
+
15
+ ### JA4Fingerprinter
16
+
17
+ TLS Client Hello fingerprinting.
18
+
19
+ ```python
20
+ from ja4plus import JA4Fingerprinter
21
+
22
+ fp = JA4Fingerprinter()
23
+ result = fp.process_packet(packet) # Returns JA4 string or None
24
+ raw = fp.get_raw_fingerprint(packet) # Returns unhashed fingerprint
25
+ ```
26
+
27
+ ### JA4SFingerprinter
28
+
29
+ TLS Server Hello fingerprinting.
30
+
31
+ ```python
32
+ from ja4plus import JA4SFingerprinter
33
+
34
+ fp = JA4SFingerprinter()
35
+ result = fp.process_packet(packet)
36
+ ```
37
+
38
+ ### JA4HFingerprinter
39
+
40
+ HTTP request fingerprinting.
41
+
42
+ ```python
43
+ from ja4plus import JA4HFingerprinter
44
+
45
+ fp = JA4HFingerprinter()
46
+ result = fp.process_packet(packet)
47
+ ```
48
+
49
+ ### JA4TFingerprinter
50
+
51
+ TCP client fingerprinting from SYN packets.
52
+
53
+ ```python
54
+ from ja4plus import JA4TFingerprinter
55
+
56
+ fp = JA4TFingerprinter()
57
+ result = fp.process_packet(packet)
58
+ ```
59
+
60
+ ### JA4TSFingerprinter
61
+
62
+ TCP server fingerprinting from SYN-ACK packets.
63
+
64
+ ```python
65
+ from ja4plus import JA4TSFingerprinter
66
+
67
+ fp = JA4TSFingerprinter()
68
+ result = fp.process_packet(packet)
69
+ ```
70
+
71
+ ### JA4LFingerprinter
72
+
73
+ Network latency estimation from TCP handshake timing.
74
+
75
+ ```python
76
+ from ja4plus import JA4LFingerprinter
77
+
78
+ fp = JA4LFingerprinter()
79
+ result = fp.process_packet(packet)
80
+ ```
81
+
82
+ ### JA4XFingerprinter
83
+
84
+ X.509 certificate structure fingerprinting.
85
+
86
+ ```python
87
+ from ja4plus import JA4XFingerprinter
88
+
89
+ fp = JA4XFingerprinter()
90
+ result = fp.fingerprint_certificate(der_bytes) # From DER-encoded cert
91
+ result = fp.process_packet(packet) # From TLS packet
92
+ details = fp.get_cert_details(x509_cert) # Extract OID details
93
+ ```
94
+
95
+ ### JA4SSHFingerprinter
96
+
97
+ SSH session classification.
98
+
99
+ ```python
100
+ from ja4plus import JA4SSHFingerprinter
101
+
102
+ fp = JA4SSHFingerprinter(packet_count=200)
103
+ result = fp.process_packet(packet)
104
+ info = fp.interpret_fingerprint(result) # Session type analysis
105
+ hassh = fp.get_hassh_fingerprints() # HASSH fingerprints
106
+ lookup = fp.lookup_hassh(hassh_value) # Known HASSH lookup
107
+ ```
108
+
109
+ ## Convenience Functions
110
+
111
+ One-shot fingerprinting without maintaining state:
112
+
113
+ ```python
114
+ from ja4plus import (
115
+ generate_ja4,
116
+ generate_ja4s,
117
+ generate_ja4h,
118
+ generate_ja4t,
119
+ generate_ja4ts,
120
+ generate_ja4l,
121
+ generate_ja4x,
122
+ generate_ja4ssh,
123
+ )
124
+
125
+ # Each takes a scapy packet and returns a fingerprint string or None
126
+ result = generate_ja4(packet)
127
+ ```
128
+
129
+ | Function | Input | Description |
130
+ |----------|-------|-------------|
131
+ | `generate_ja4(packet)` | scapy packet | JA4 TLS client fingerprint |
132
+ | `generate_ja4s(packet)` | scapy packet | JA4S TLS server fingerprint |
133
+ | `generate_ja4h(packet)` | scapy packet | JA4H HTTP fingerprint |
134
+ | `generate_ja4t(packet)` | scapy packet | JA4T TCP client fingerprint |
135
+ | `generate_ja4ts(packet)` | scapy packet | JA4TS TCP server fingerprint |
136
+ | `generate_ja4l(packet)` | scapy packet | JA4L latency fingerprint |
137
+ | `generate_ja4x(cert_info)` | dict | JA4X certificate fingerprint (takes cert_info dict) |
138
+ | `generate_ja4ssh(packet)` | scapy packet | JA4SSH session fingerprint |
139
+
140
+ ## Utility Modules
141
+
142
+ ### ja4plus.utils.tls_utils
143
+
144
+ | Function | Description |
145
+ |----------|-------------|
146
+ | `extract_tls_info(packet)` | Extract TLS handshake details from a packet |
147
+ | `is_grease_value(value)` | Check if a value is a GREASE value |
148
+ | `parse_client_hello(data)` | Parse raw ClientHello bytes |
149
+ | `parse_server_hello(data)` | Parse raw ServerHello bytes |
150
+
151
+ ### ja4plus.utils.http_utils
152
+
153
+ | Function | Description |
154
+ |----------|-------------|
155
+ | `extract_http_info(packet)` | Extract HTTP request details from a packet |
156
+ | `is_http_request(data)` | Check if data is an HTTP request |
157
+ | `parse_http_request(data)` | Parse raw HTTP request bytes |
158
+
159
+ ### ja4plus.utils.ssh_utils
160
+
161
+ | Function | Description |
162
+ |----------|-------------|
163
+ | `is_ssh_packet(data)` | Check if data is SSH traffic |
164
+ | `parse_ssh_packet(data)` | Parse SSH packet structure |
165
+ | `extract_hassh(data)` | Extract HASSH fingerprint from KEXINIT |
166
+
167
+ ### ja4plus.utils.x509_utils
168
+
169
+ | Function | Description |
170
+ |----------|-------------|
171
+ | `oid_to_hex(oid_string)` | Convert OID dotted string to ASN.1 hex encoding |