feat: add certificate fetching utility with Android 7.0+ TLS 1.2 support#5745
feat: add certificate fetching utility with Android 7.0+ TLS 1.2 support#5745iamobin wants to merge 2 commits into
Conversation
Add CertificateFetcher utility to fetch SSL/TLS certificates from remote servers and generate SHA-256 fingerprints for certificate pinning. Key features: - Fetch certificate chains from domains with optional port specification - Generate SHA-256 fingerprints for certificate pinning - Support custom SNI (Server Name Indication) configuration - Optional insecure mode for testing/development - Proper TLS 1.2+ support on Android 7.0-7.1 via Conscrypt - Material3 button integration in TLS configuration UI Technical implementation: - Uses OkHttp with Conscrypt security provider for modern TLS support - Implements custom X509TrustManager to capture certificates during handshake - Supports TLS 1.2 and 1.3 with appropriate connection specs - Coroutine-based async execution on IO dispatcher Dependencies added: - org.conscrypt:conscrypt-android:2.5.2
There was a problem hiding this comment.
Pull request overview
This PR introduces a certificate-fetching utility and UI integration to help users obtain SHA-256 certificate fingerprints for TLS pinning, including adding Conscrypt to improve TLS 1.2+ support on Android 7.0–7.1.
Changes:
- Added
CertificateFetcherutility to fetch server certificate chains and compute SHA-256 fingerprints. - Integrated a “Fetch Certificate” button into TLS configuration UI and wired it in
ServerActivity. - Added Conscrypt dependency via version catalog + app Gradle deps.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
V2rayNG/gradle/libs.versions.toml |
Adds Conscrypt version + library coordinates to the version catalog. |
V2rayNG/app/build.gradle.kts |
Includes Conscrypt dependency in the app module. |
V2rayNG/app/src/main/res/values/strings.xml |
Adds UI strings for certificate fetch flow (loading/success/error). |
V2rayNG/app/src/main/res/layout/layout_tls.xml |
Adds a Material3 “Fetch” button next to the pinned cert fingerprint input. |
V2rayNG/app/src/main/res/layout/layout_tls_hysteria2.xml |
Adds the same “Fetch” button for Hysteria2 TLS layout. |
V2rayNG/app/src/main/java/com/v2ray/ang/util/CertificateFetcher.kt |
New utility for fetching certificate chains and generating SHA-256 fingerprints. |
V2rayNG/app/src/main/java/com/v2ray/ang/ui/ServerActivity.kt |
Wires the button to fetch fingerprints and populate the pinned fingerprint field. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| val defaultTrustManager = runCatching { createDefaultTrustManager() }.getOrNull() | ||
|
|
||
| return object : X509TrustManager { |
| private fun parseDomainAndPort(domain: String): Pair<String, Int> { | ||
| val parts = domain.split(":", limit = 2) | ||
| return if (parts.size == 2) { | ||
| Pair(parts[0], parts[1].toIntOrNull() ?: 443) | ||
| } else { | ||
| Pair(domain, 443) | ||
| } | ||
| } |
| runCatching { | ||
| client.newCall(request).execute().close() | ||
| }.onFailure { exception -> | ||
| if (exception is javax.net.ssl.SSLHandshakeException && capturedCertificates.isNullOrEmpty()) { | ||
| return@withContext CertificateResult( | ||
| fingerprints = emptyList(), | ||
| error = "SSL handshake failed: ${exception.message}" | ||
| ) | ||
| } | ||
| } |
| val port = et_port.text.toString().trim() | ||
| val domain = if (port.isNotEmpty() && Utils.parseInt(port) > 0) { | ||
| "$address:$port" | ||
| } else { | ||
| address | ||
| } |
| return OkHttpClient.Builder() | ||
| .sslSocketFactory(sslContext.socketFactory, trustManager) | ||
| .connectionSpecs(listOf(connectionSpec, ConnectionSpec.COMPATIBLE_TLS)) | ||
| .hostnameVerifier { hostname, _ -> hostname == sni || hostname == host } | ||
| .connectTimeout(10, TimeUnit.SECONDS) | ||
| .readTimeout(10, TimeUnit.SECONDS) | ||
| .build() |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
|
感谢 PR
|
|
AI 有些分析的不对的可以不用处理,处理下你觉得合理的 |
I did some testing and research on this. If we want to remove Conscrypt, we should drop support for SDK 24–28 and only support API 29+. On Android 10 (API 29) and above, TLS 1.3 is available natively without needing Conscrypt, and everything works as expected in my tests. But on API 24–28, removing Conscrypt causes compatibility issues, so keeping it is still required for those versions. |
Add CertificateFetcher utility to fetch SSL/TLS certificates from remote servers and generate SHA-256 fingerprints for certificate pinning.
Key features:
Technical implementation:
Dependencies added: