You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

首次启动AWS Kinesis WebRTC流时触发SSLPeerUnverifiedException异常

问题描述

我用AWS Kinesis WebRTC实现摄像头实时视频流功能,应用首次安装启动时,在创建连接阶段崩溃,抛出SSLPeerUnverifiedException异常;但重启设备或应用后就能正常运行,试了不少线上方案都没解决。

触发异常的代码行

val describeSignalingChannelResult = awsKinesisVideoClient?.describeSignalingChannel(
    DescribeSignalingChannelRequest()
        .withChannelName(channelName)
)

异常信息

EXCEPTION: DefaultDispatcher-worker-1
Process: com.secure56.app, PID: 26211
com.amazonaws.AmazonClientException: Unable to execute HTTP request: Hostname kinesisvideo.ap-south-1.amazonaws.com not verified:
    certificate: sha1/------------------
    DN: CN=kinesisvideo.ap-south-1.amazonaws.com
    subjectAltNames: [kinesisvideo.ap-south-1.amazonaws.com]
    at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:456)
    at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:229)
    at com.amazonaws.services.kinesisvideo.AWSKinesisVideoClient.invoke(AWSKinesisVideoClient.java:2077)
    at com.amazonaws.services.kinesisvideo.AWSKinesisVideoClient.describeSignalingChannel(AWSKinesisVideoClient.java:930)
    at com.android56.app.onecam.kvs.SignallingDataCreator.updateSignallingChannelInfoTask(SignallingDataCreator.kt:158)
    at com.android56.app.onecam.kvs.SignallingDataCreator$updateSignallingChannelInfoTask$1.invokeSuspend(Unknown Source:15)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
    at kotlinx.coroutines.internal.LimitedDispatcher.run(LimitedDispatcher.kt:42)
    at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:95)
    at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@fb144, Dispatchers.IO]
Caused by: javax.net.ssl.SSLPeerUnverifiedException: Hostname kinesisvideo.ap-south-1.amazonaws.com not verified:
    certificate: sha1/z60CQXD0myU9Ol4CyrQpESqcV3Y=
    DN: CN=kinesisvideo.ap-south-1.amazonaws.com
    subjectAltNames: [kinesisvideo.ap-south-1.amazonaws.com]
    at com.android.okhttp.internal.io.RealConnection.connectTls(RealConnection.java:1480)
    at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:1415)
    at com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:1359)
    at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:221)
    at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:144)
    at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:106)
    at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:400)
    at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:333)
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:483)
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:135)
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:266)
    at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getOutputStream(DelegatingHttpsURLConnection.java:219)
    at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:30)
    at com.google.firebase.perf.network.InstrURLConnectionBase.getOutputStream(InstrURLConnectionBase.java:165)
    at com.google.firebase.perf.network.InstrHttpsURLConnection.getOutputStream(InstrHttpsURLConnection.java:89)
    at com.amazonaws.http.UrlHttpClient.writeContentToConnection(UrlHttpClient.java:162)
    at com.amazonaws.http.UrlHttpClient.execute(UrlHttpClient.java:75)
    at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:386)

依赖配置

def aws_version = '2.68.0'
implementation("com.amazonaws:aws-android-sdk-kinesisvideo:$aws_version@aar") { 
    transitive = true 
}
implementation("com.amazonaws:aws-android-sdk-kinesisvideo-signaling:$aws_version@aar") { 
    transitive = true 
}
implementation("com.amazonaws:aws-android-sdk-kinesisvideo-webrtcstorage:$aws_version@aar") { 
    transitive = true 
}
implementation('org.glassfish.tyrus.bundles:tyrus-standalone-client:1.20') { 
    exclude module: 'javax.inject' 
}
implementation 'org.awaitility:awaitility:3.0.0'
解决方案

这个问题大概率是首次启动时Android系统SSL证书缓存未加载完成,或是AWS SDK证书验证逻辑在首次初始化时存在异常,可尝试以下方案:

  • 预加载AWS根证书
    把AWS根证书打包到应用资源中,手动初始化SSL上下文时加载该证书,避免依赖系统证书缓存。在初始化AWSKinesisVideoClient前,配置自定义ClientConfiguration:

    val clientConfig = ClientConfiguration()
    val sslContext = SSLContext.getInstance("TLS")
    val trustManager = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()).apply {
        val certInputStream = context.resources.openRawResource(R.raw.amazon_root_ca)
        val keyStore = KeyStore.getInstance(KeyStore.getDefaultType()).apply {
            load(null, null)
            val cf = CertificateFactory.getInstance("X.509")
            val cert = cf.generateCertificate(certInputStream)
            setCertificateEntry("AmazonRootCA", cert)
        }
        init(keyStore)
    }.trustManagers[0] as X509TrustManager
    sslContext.init(null, arrayOf(trustManager), SecureRandom())
    clientConfig.sslSocketFactory = sslContext.socketFactory
    
    val awsKinesisVideoClient = AWSKinesisVideoClientBuilder.standard()
        .withClientConfiguration(clientConfig)
        .withRegion(Regions.AP_SOUTH_1)
        .withCredentials(yourCredentialsProvider)
        .build()
    
  • 添加重试机制
    针对首次启动的SSL异常添加重试逻辑,因为重启后正常说明后续尝试能通过验证:

    suspend fun getSignalingChannelInfo(channelName: String): DescribeSignalingChannelResult? {
        repeat(3) { attempt ->
            return try {
                awsKinesisVideoClient?.describeSignalingChannel(
                    DescribeSignalingChannelRequest().withChannelName(channelName)
                )
            } catch (e: SSLPeerUnverifiedException) {
                if (attempt == 2) throw e
                delay(1000)
                null
            }
        }
        return null
    }
    
  • 升级AWS SDK版本
    当前使用的2.68.0版本较旧,后续版本可能修复了首次启动的SSL验证问题,尝试升级到较新的稳定版本。

  • 排查Firebase Performance干扰
    异常栈中出现Firebase性能监控的网络拦截类,有可能是其拦截逻辑导致SSL验证异常。可临时禁用该功能,确认是否解决问题,再调整Firebase Perf配置避免拦截AWS请求。


内容的提问来源于stack exchange,提问作者anil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 05:44:54