android - 在 kSoap2 中使用 TLS1.2 客户端证书

标签 android soap tls1.2 android-ksoap2

我正在尝试使用 kSoap2 和 EasyWSDL 将我的 Android 应用程序连接到受 TLS 保护的 SOAP 端点,但出现以下异常:

W/System.err: javax.net.ssl.SSLHandshakeException: Connection closed by peer
                  at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
                  at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:351)
                  at com.android.okhttp.internal.io.RealConnection.connectTls(RealConnection.java:192)
                  at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:149)
W/System.err:     at com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:112)
                  at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:184)
                  at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:126)
                  at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:95)
W/System.err:     at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:281)
                  at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:224)
                  at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:461)
                  at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:127)
                  at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:258)
                  at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getOutputStream(DelegatingHttpsURLConnection.java:218)
                  at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getOutputStream(Unknown Source:0)
                  at org.ksoap2.transport.HttpsServiceConnectionSE.openOutputStream(HttpsServiceConnectionSE.java:127)
                  at com.easywsdl.exksoap2.mtom.MTOMTransportImplementation.sendData(MTOMTransportImplementation.java:65)
                  at com.easywsdl.exksoap2.transport.AdvancedHttpsTransportSE.sendData(AdvancedHttpsTransportSE.java:39)
                  at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:184)
                  at com.easywsdl.exksoap2.transport.AdvancedHttpsTransportSE.call(AdvancedHttpsTransportSE.java:51)

这是我配置传输的方式:

@Override
    protected Transport createTransport() {
        Transport transport = super.createTransport();
        try {
            if(transport instanceof HttpsTransportSE) {
                HttpsTransportSE httpsTransport = (HttpsTransportSE)transport;
                if(httpsTransport.getServiceConnection() instanceof HttpsServiceConnectionSE) {
                    HttpsServiceConnectionSE httpsServiceConnection = (HttpsServiceConnectionSE)httpsTransport.getServiceConnection();
                    httpsServiceConnection.setSSLSocketFactory(getSSLSocketFactory());
                }
            }
        } catch (IOException e) {
            Log.e(TAG, "Could not add key store", e);
        } catch (NoSuchAlgorithmException e) {
            Log.e(TAG, "Could not add key store", e);
        } catch (KeyStoreException e) {
            Log.e(TAG, "Could not add key store", e);
        } catch (KeyManagementException e) {
            Log.e(TAG, "Could not add key store", e);
        }
        this.transport = transport;
        return transport;
    }

    private SSLSocketFactory getSSLSocketFactory() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(keyStore);
        SSLContext context = SSLContext.getInstance("TLS");
        context.init(null, tmf.getTrustManagers(), null);
        return context.getSocketFactory();
    }

我不确定如何解决这个问题,或者我是否正确使用了 keystore 。请帮忙。

最佳答案

解决方案是也配置 key 管理器:

val keystore = KeyStore.getInstance("BKS")                                                  
keystore.load(assets.open("keystore.bks"), password)

// Create key manager
val keyManagerFactory = 
KeyManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())                                 
keyManagerFactory.init(keystore, password)
val keyManagers = keyManagerFactory.keyManagers

// Create trust manager
val trustManagerFactory = 
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())                                                   
trustManagerFactory.init(keystore)
val trustManagers = trustManagerFactory.trustManagers

SSLContext context = SSLContext.getInstance("TLSv1.2");
context.init(this.keyManagers, this.trustManagers, null);
return context.getSocketFactory();

关于android - 在 kSoap2 中使用 TLS1.2 客户端证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50698530/

相关文章:

wordpress - 如何从 Wordpress 表单调用 SOAP Web 服务?

ios - 在 iOS App 上安装 TLS 1.2 证书

android - 如何从应用程序 NotificationChannel >=Oreo 获取 getSound()、getName()

java - 静态全局变量无法解析

java - 如何在现有 SOAP Web 服务上添加 "Authentication"?

c++ - 从 BCRYPT_SECRET_HANDLE 将共享 secret 导出为 BYTE 数组

email - PHP imap_open()、OpenSSL 和无密码

android - 使用新的 App Startup API 初始化实例

android - ADT版本未升级

android - 为什么在使用主页按钮离开时我的 Activity 会导致内存泄漏?