Every HTTPS connection you make goes through a TLS library. If you're using Chrome, Android, or Cloudflare — that library is BoringSSL.
And if you build web scrapers, your TLS library choice determines whether anti-bot systems flag you or let you through.
This guide covers what BoringSSL actually is, how it differs from OpenSSL, who uses it, and why it's become a critical piece of the web scraping fingerprinting puzzle.
What Is BoringSSL?
BoringSSL is Google's open-source fork of OpenSSL, the widely used cryptography and TLS library. Google created it in 2014 to consolidate the 70+ patches they were maintaining on top of OpenSSL across Chrome, Android, and internal services. It strips out legacy code, removes outdated cipher suites, and prioritizes security and maintainability over backward compatibility. Chrome, Android, Cloudflare, and Fastly all use BoringSSL for their TLS connections.
Why Did Google Fork OpenSSL?
Google didn't fork OpenSSL on a whim. By 2014, they had a real maintenance problem.
Google's products — Chrome, Android, internal servers — all used OpenSSL. But each product needed different patches applied on top of it. Over time, Google accumulated more than 70 custom patches.
Some of those patches were too experimental for upstream OpenSSL to accept. Others conflicted with OpenSSL's promise of API and ABI stability. Rebasing all those patches every time OpenSSL released an update was eating engineering time.
Then Heartbleed happened. The 2014 OpenSSL vulnerability exposed private memory from millions of servers, including encryption keys and user data. It demonstrated that OpenSSL's massive codebase — full of legacy code paths nobody actively maintained — was a liability.
Google's answer was to fork OpenSSL, strip it down, and maintain it under their own terms. They named it BoringSSL because the goal was to make SSL boring again: predictable, minimal, and secure.
BoringSSL vs OpenSSL: Key Differences
The two libraries share DNA, but they've diverged in philosophy and practice.
| Dimension | BoringSSL | OpenSSL |
|---|---|---|
| Maintainer | OpenSSL Software Foundation | |
| API stability | None guaranteed | Stable across minor versions |
| Release model | Rolling (no versioned releases) | Numbered releases (3.x, etc.) |
| Legacy cipher support | Removed aggressively | Retained for compatibility |
| Intended audience | Google products, embedded use | General-purpose, system library |
| FIPS 140 support | Yes (separate validated module) | Yes (OpenSSL FIPS provider) |
| Documentation | Header file comments, markdown docs | Extensive man pages, website |
| Community | Google-internal primarily | Large open-source community |
API Stability
This is the biggest practical difference. OpenSSL promises that code compiled against version 3.0 will work with 3.1. BoringSSL makes no such promise.
Google's position is explicit: programs that use BoringSSL ship their own copy and update it on their own schedule. This lets Google refactor aggressively without worrying about breaking external consumers.
If you're embedding BoringSSL in your own project, you're signing up for a "live at head" model. Pin to a commit, test, update regularly.
Removed Features
BoringSSL stripped out a lot of code that OpenSSL carries for backward compatibility. Weak CBC ciphers, legacy SSL protocol versions, rarely-used algorithms — all gone or reduced.
When Fastly migrated from OpenSSL to BoringSSL in 2023, they discovered that weak CBC ciphers were silently dropped. At their scale, even a tiny percentage of clients using those ciphers represented real traffic.
The BoringSSL team ended up re-adding one specific cipher (ECDHE-RSA-AES128-SHA256) to avoid breaking legitimate clients.
Security Posture
BoringSSL's smaller codebase means fewer places for bugs to hide. Google runs continuous fuzzing, internal security reviews, and integrates fixes quickly since there's no release cycle to wait for.
That said, BoringSSL isn't immune to vulnerabilities. And OpenSSL has invested heavily in code quality since Heartbleed, including paid full-time developers and regular audits.
Neither library is "more secure" by default. BoringSSL is more opinionated — it forces modern configurations. OpenSSL is more flexible — which can be a strength or a footgun depending on who's configuring it.
Who Uses BoringSSL?
BoringSSL powers more internet traffic than most people realize.
Chrome and Chromium use BoringSSL for all TLS connections. Every HTTPS page load in Chrome goes through it.
Android ships BoringSSL as its SSL library, though it's not exposed through the NDK. Apps on Android that use the platform's networking stack are using BoringSSL under the hood.
Cloudflare migrated their entire edge SSL termination stack to BoringSSL. They documented the process in detail, noting gains in TLS 1.3 support, X25519 key exchange, and RSA-PSS signatures that were harder to deploy on OpenSSL.
Fastly replaced OpenSSL with BoringSSL across their CDN to reduce CVE response overhead and improve their security posture.
Several other projects — including gRPC, the Go standard library's crypto packages, and various Google Cloud services — depend on BoringSSL or its derivatives.
BoringSSL and TLS Fingerprinting
Here's where BoringSSL gets directly relevant if you work in web scraping, bot detection, or network security.
Every TLS client generates a unique fingerprint based on how it constructs the ClientHello message during the TLS handshake. This happens before any HTTP data is exchanged — before headers, cookies, or user-agent strings.
The ClientHello contains the TLS version, supported cipher suites, extensions, elliptic curves, and compression methods. The order and specific values differ between TLS libraries.
Chrome uses BoringSSL. Firefox uses NSS. Python's requests library uses OpenSSL. Safari uses Apple's Secure Transport.
Anti-bot systems like Cloudflare, Akamai, and DataDome maintain databases of known TLS fingerprints. When a request claims to be Chrome (via its User-Agent header) but produces an OpenSSL fingerprint, the mismatch gets flagged immediately.
JA3 and JA4 Fingerprinting
The standard algorithms for TLS fingerprinting are JA3 and its successor JA4. JA3 was published by Salesforce researchers in 2017.
JA3 works by extracting five fields from the ClientHello — TLS version, cipher suites, extensions, elliptic curves, and elliptic curve point formats — concatenating their decimal values, and hashing the result with MD5.
Every TLS library produces a different JA3 hash. A scraper using Python's default requests library will produce a JA3 hash that looks nothing like Chrome's. This makes it trivial for servers to detect and block automated traffic.
JA4 improves on JA3 with a more structured format that includes the TLS version, SNI presence, number of ciphers, number of extensions, ALPN value, and sorted cipher/extension lists. It's harder to spoof and gives defenders more granular information.
Why This Matters for Web Scraping
If you're building scrapers that need to access sites protected by modern anti-bot systems, your TLS fingerprint is the first thing they check.
Sending requests with Python's requests or httpx using their default OpenSSL-backed TLS configuration is like wearing a name tag that says "I am a bot." The fingerprint doesn't match any browser.
To avoid detection, your scraper's TLS handshake needs to match a real browser. Since Chrome holds the majority of browser market share, that usually means producing a BoringSSL-compatible fingerprint.
Matching BoringSSL Fingerprints in Practice
There are several open-source tools that address this problem. Each takes a different approach.
curl-impersonate patches curl to use BoringSSL (for Chrome profiles) or NSS (for Firefox profiles) instead of its default OpenSSL. It also adjusts cipher suite order, extensions, and HTTP/2 settings to match real browser configurations.
This code sets up curl_cffi in Python — a library that wraps curl-impersonate — to produce Chrome-identical TLS fingerprints:
from curl_cffi import requests
# The impersonate parameter selects a browser profile
# This configures BoringSSL cipher suites, extensions, and HTTP/2 settings
response = requests.get(
"https://example.com",
impersonate="chrome124",
proxies={"https": "http://user:pass@proxy:port"}
)
print(response.status_code)
print(response.text[:500])
The impersonate="chrome124" parameter is doing the heavy lifting. Under the hood, it swaps the TLS library to BoringSSL, sets the exact cipher suite order Chrome 124 uses, configures matching TLS extensions, and adjusts HTTP/2 frame settings.
tls-client and rnet are similar tools. rnet is a Rust-based Python HTTP client that uses BoringSSL directly and supports browser profile mimicry. tls-client offers Go and Python bindings with predefined browser fingerprint profiles.
Headless browsers (Playwright, Puppeteer) sidestep the problem entirely because they use a real Chromium instance — which already runs BoringSSL. The fingerprint is authentic by default. The tradeoff is resource usage: running full browser instances is 10-50x more expensive than HTTP requests.
Keeping Fingerprint Profiles Current
Browser TLS fingerprints change with every major release. Chrome 120 and Chrome 130 produce different JA3/JA4 hashes because Google updates BoringSSL's cipher suite preferences, adds new extensions, or changes ALPN negotiation.
If your scraper uses a stale profile — say, impersonating Chrome 110 when current Chrome traffic is on 130 — anti-bot systems will notice. The fingerprint is valid but outdated, which is itself a detection signal.
Tools like curl-impersonate and rnet publish updated profiles with each browser release. Check for updates monthly and pin to profiles no more than two versions behind the current stable release.
Proxy Rotation and TLS Fingerprinting
Getting the TLS fingerprint right is only half the equation. If you're sending hundreds of requests with the same IP address, fingerprint accuracy won't save you.
Residential proxies rotate your source IP across real consumer connections, making each request appear to originate from a different household. Combined with a BoringSSL-matched TLS fingerprint, this produces traffic that closely resembles organic browser activity.
The combination matters. A perfect BoringSSL fingerprint from a datacenter IP still looks suspicious. A residential IP with a Python/OpenSSL fingerprint still gets flagged. You need both layers.
How to Build BoringSSL From Source
If you need BoringSSL for a custom project — embedding it in a C/C++ application, or testing TLS configurations — here's how to build it.
Prerequisites: a C11/C++17 compiler, CMake 3.22+, Go (latest stable), and Ninja (recommended over Make).
# Clone the repository
git clone https://boringssl.googlesource.com/boringssl
cd boringssl
# Create build directory and configure with CMake
# Ninja is recommended for faster builds
cmake -B build -GNinja
# Build the library and run tests
ninja -C build
ninja -C build run_tests
On Windows, you'll also need NASM for assembly support. Set CMAKE_ASM_NASM_COMPILER if CMake can't find it automatically.
Two build flags worth knowing: OPENSSL_NO_ASM disables assembly optimizations (useful for sanitizer compatibility but significantly slower), and OPENSSL_SMALL trades performance for reduced binary size.
Remember: BoringSSL has no versioned releases. You clone the repo, pin to a specific commit, and update manually. The INCORPORATING.md file in the repo has detailed instructions for embedding it in existing build systems.
BoringSSL vs LibreSSL: The Other OpenSSL Fork
BoringSSL wasn't the only project born from OpenSSL's Heartbleed crisis. The OpenBSD team forked OpenSSL into LibreSSL around the same time.
| Dimension | BoringSSL | LibreSSL |
|---|---|---|
| Creator | OpenBSD Foundation | |
| Goal | Meet Google's internal needs | Drop-in OpenSSL replacement |
| API compatibility | Not a priority | Explicitly maintained |
| Target users | Google products, embedded use | BSD systems, OpenSSL replacements |
| Legacy code removal | Aggressive | Aggressive but compatibility-aware |
The key distinction: LibreSSL aims to be a drop-in replacement for OpenSSL with a cleaner codebase. BoringSSL doesn't care about being a replacement for anything — it exists to serve Google's products.
For developers choosing between them, the decision is straightforward. If you need OpenSSL API compatibility, LibreSSL is the better fit. If you're building something Google-adjacent (Android, Chromium, gRPC) or need BoringSSL's specific TLS fingerprint characteristics, use BoringSSL.
BoringSSL and Post-Quantum Cryptography
BoringSSL is one of the first major TLS libraries to ship post-quantum key exchange in production. Google has been experimenting with hybrid post-quantum algorithms in Chrome since 2023.
The concern is straightforward: quantum computers capable of breaking current public-key cryptography may arrive within the next decade.
An attacker recording encrypted traffic today could decrypt it later once quantum hardware matures. This "harvest now, decrypt later" threat is why post-quantum migration is happening before quantum computers actually exist.
BoringSSL currently supports hybrid key exchange using Kyber (ML-KEM) combined with X25519. The hybrid approach means the connection is protected by both a classical and a post-quantum algorithm — if either one holds, the connection stays secure.
For web scraping, post-quantum support adds another fingerprinting dimension. Chrome's ClientHello now includes post-quantum key share extensions that older TLS libraries don't support. As adoption spreads, scraper fingerprints will need to account for these extensions too.
Common Questions About BoringSSL
Is BoringSSL Free to Use?
Yes. BoringSSL is open source under a combination of the OpenSSL License, ISC License, and BSD licenses. You can use it in commercial projects without paying licensing fees.
Can I Use BoringSSL as a System-Wide OpenSSL Replacement?
No, and Google explicitly recommends against it. BoringSSL has no stable API, no versioned releases, and can break your code at any commit. It's designed to be vendored into specific projects, not installed as a shared system library.
Does BoringSSL Support FIPS 140?
Yes. BoringSSL includes a FIPS 140-3 validated cryptographic module. Building with the -DFIPS=1 CMake flag enables the FIPS module, which includes integrity checks, known-answer tests, and other compliance requirements.
How Often Is BoringSSL Updated?
Continuously. There are no scheduled releases. Google pushes changes to the main branch as they're ready.
Consumers are expected to track the head and update regularly. Tagged snapshots exist for build systems that require them, but they don't represent stability milestones.
Do I Need BoringSSL for Web Scraping?
You don't need to build BoringSSL yourself. What you need is a TLS fingerprint that matches a BoringSSL-powered browser like Chrome.
Libraries like curl_cffi, rnet, and tls-client handle this for you. They bundle BoringSSL internally and expose browser profile selection through simple configuration options.
Wrapping Up
BoringSSL is Google's stripped-down, opinionated fork of OpenSSL. It trades backward compatibility for a smaller, more auditable codebase that ships modern TLS defaults by default.
For most developers, you're already using it — through Chrome, Android, or any service behind Cloudflare.
For web scraping engineers, understanding BoringSSL's TLS fingerprint is the difference between requests that pass anti-bot checks and requests that get blocked before a single byte of HTML is returned.
Match the fingerprint, rotate your IPs, and respect rate limits. That's the playbook.