Java17升级后Android 10+无法建立WSS连接问题
Java 8升级到17后Android API30+设备WSS连接失败问题
将Java版本从8升级到17后,Android应用在API 30+设备上无法与服务器建立安全WebSocket(WSS)连接,始终抛出如下错误:
javax.websocket.DeploymentException: The HTTP request to initiate the WebSocket connection to [wss://192.168.0.213:8080/input] failed at org.apache.tomcat.websocket.WsWebSocketContainer.connectToServerRecursive(WsWebSocketContainer.java:480) at org.apache.tomcat.websocket.WsWebSocketContainer.connectToServer(WsWebSocketContainer.java:185) at org.springframework.web.socket.client.standard.StandardWebSocketClient.lambda$doHandshakeInternal$0$org-springframework-web-socket-client-standard-StandardWebSocketClient(StandardWebSocketClient.java:151) at org.springframework.web.socket.client.standard.StandardWebSocketClient$$ExternalSyntheticLambda0.call(Unknown Source:10) at java.util.concurrent.FutureTask.run(FutureTask.java:264) at java.lang.Thread.run(Thread.java:1012) Caused by: java.util.concurrent.ExecutionException: javax.net.ssl.SSLException: Bytes were consumed from the input during a write at org.apache.tomcat.websocket.AsyncChannelWrapperSecure$WrapperFuture.get(AsyncChannelWrapperSecure.java:518) at org.apache.tomcat.websocket.WsWebSocketContainer.connectToServerRecursive(WsWebSocketContainer.java:329) .. 5 common frames omitted Caused by: javax.net.ssl.SSLException: Bytes were consumed from the input during a write at org.apache.tomcat.websocket.AsyncChannelWrapperSecure$WebSocketSslHandshakeThread.checkResult(AsyncChannelWrapperSecure.java:440) at org.apache.tomcat.websocket.AsyncChannelWrapperSecure$WebSocketSslHandshakeThread.run(AsyncChannelWrapperSecure.java:381)
实现代码
Security.addProvider(BouncyCastleProvider()) val keyStore = KeyStore.getInstance("PKCS12", BouncyCastleProvider()) val keyFile = ComponentProvider.instance.keyFile keyStore.load(keyFile, KEY_STORE_PASSWORD.toCharArray()) val keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()) keyManagerFactory.init(keyStore, KEY_STORE_PASSWORD.toCharArray()) val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()) trustManagerFactory.init(keyStore) val sslContext = SSLContext.getInstance("TLS") sslContext.init(keyManagerFactory.keyManagers, trustManagerFactory.trustManagers, null) val container = ContainerProvider.getWebSocketContainer() val webSocketClient = StandardWebSocketClient(container) webSocketClient.userProperties = mapOf(Pair("org.apache.tomcat.websocket.SSL_CONTEXT", sslContext)) val converter = MappingJackson2MessageConverter() converter.objectMapper = JsonMapper.builder().addModule(JavaTimeModule()).build() val webSocketStompClient = WebSocketStompClient(webSocketClient) Thread{ webSocketStompClient.connect(ComponentProvider.instance.baseUrl, sessionHandler) }.start()
其中keyFile为PKCS12格式的密钥库,baseUrl为服务器地址。
应用配置信息
compileSdk = 34 defaultConfig { minSdk = 28 targetSdk = 33 versionCode = 1 versionName = "1.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } compileOptions { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { jvmTarget = "17" }
相关依赖
java { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 } dependencies { implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.20' implementation 'com.google.code.gson:gson:2.10.1' implementation 'org.springframework.boot:spring-boot-starter-websocket:2.7.0' implementation 'org.springframework:spring-messaging:6.0.13' }
已尝试的解决方案
- 更换服务器证书、使用自签名证书
- 采用旧方法实现连接
- 替换KeyManagerFactory为null或使用错误密钥库
- 配置
networkSecurityConfig引入DER格式证书
以上尝试均未解决问题,且相同密钥库与代码在桌面端运行正常。
更新信息
连接总是在三次尝试后成功,通过Wireshark发现客户端Hello使用TLSv1.0,服务器发送"change cipher spec"后报错,第三次客户端回复该消息后连接成功。
内容的提问来源于stack exchange,提问作者Lugalkiennn
相关产品推荐
相关产品推荐

