Android 29+使用自签名证书实现MTLS遇SSL握手错误求助
Android自签名证书MTLS握手错误排查
背景
两周前我将Go项目中基于自签名X509证书的MTLS-Fetch功能移植到Android平台,用于副业项目的Android端。Go端实现可正常运行,核心函数如下:
func (a *App) MTLSFetch(method string, path string, body string, csr string, privateKey string) MTLSFetchResponse { ... }
问题现象
Android端尝试不依赖外部库实现MTLS连接,核心代码片段如下:
KeyStore = KeyStore.getInstance("AndroidKeyStore"); keyStore.setKeyEntry(this.alias, privateKey, null, new Certificate[]{originalCert}); CustomX509TrustManager trustManager = new CustomX509TrustManager(getCertificate()); // 自定义信任管理器,信任所有证书 TrustManager[] trustManagers = {trustManager}; SSLContext sslContext = SSLContext.getInstance("TLS"); KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("PKIX"); keyManagerFactory.init(this.keyStore, null); sslContext.init(keyManagerFactory.getKeyManagers(), trustManagers, null); SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); HttpsURLConnection ctx; InputStream o; URL url2 = new URL(url); ctx = (HttpsURLConnection) url2.openConnection(); ctx.setSSLSocketFactory(sslSocketFactory); ctx.setHostnameVerifier((hostname, session) -> true); ctx.setRequestMethod(method); ctx.connect();
但始终遭遇SSL握手错误,主要出现两种错误信息:
javax.net.ssl.SSLHandshakeException: Error configuring certificate: ssl=0x7661414de2d8: 06-04 12:36:35.697 12178 12196 E Blockguard: error:1000012e:SSL routines:OPENSSL_internal:KEY_USAGE_BIT_INCORRECT (external/boringssl/src/ssl/ssl_cert.cc:605 0x76605a5d1112:0x00000000)06-04 12:36:35.697 12178 12196 E Blockguard: error:100000e4:SSL routines:OPENSSL_internal:UNKNOWN_CERTIFICATE_TYPE (external/boringssl/src/ssl/ssl_cert.cc:249 0x76605a5d1112:0x00000000)
已执行的排查操作
- 测试代码声明了INTERNET权限:
@RequiresPermission(Manifest.permission.INTERNET) @Test public void mtlsTest() throws Exception{
- AndroidManifest.xml中配置了必要权限:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.USE_CREDENTIALS" /> <application> <service android:name=".plugin.MyVpnService" android:permission="android.permission.BIND_VPN_SERVICE" android:exported="true"> <intent-filter> <action android:name="android.net.VpnService" /> </intent-filter> </service> </application> </manifest>
- 尝试过多种证书与私钥的解析方式,甚至在运行时生成新的密钥对(同一证书和私钥组合在Go端可正常工作)
- 使用BC包版本为bcXXX-jdk18on:1.78.1,尝试更换过BC、bcjsse等加密提供者,修改KeyStore和KeyManagerFactory的提供者配置
- 通过X509v3CertificateBuilder重新生成证书,确认扩展配置符合要求:
X509v3 extensions: X509v3 Key Usage: critical Key Encipherment, Data Encipherment X509v3 Extended Key Usage: TLS Web Client Authentication X509v3 Basic Constraints: critical CA:FALSE
- 测试过多种HTTPS连接实现:Android原生HttpsURLConnection、OkHttp 4.12.0、Retrofit 2.11.0搭配OkHttp,以及原始Socket实现,均出现相同错误
- 应用限制:无法提前在设备上安装证书,必须在运行时生成并使用
内容的提问来源于stack exchange,提问作者leon
相关产品推荐
相关产品推荐

