Client certificate does not work with Android - How to debug?

I am trying to implement client certificate communication for an Android application, so far without much success - and it seems that this feature, if at all possible, is very complicated. The full thread that I am implementing is described in my previous question .

I followed the code and code from this blog post , describing the same scenario, more or less, with no results.

What does not work: Opening an SSL connection ( HttpsURLConnection) between the Android client and the server causes the server to return a 403 status code .
AFAIK, this 403 is explained by the fact that the server does not receive or does not trust the client certificate that it receives, and I am not sure how to debug it.

What works:

  • Create a PKCS # 10 request, send it to the CA, and receive a signed PKCS # 7 (P7B)
  • Saving the received P7B with the private key in KeyStore and exporting it to PKCS # 12 (P12)
  • ( Most anonymous ), choosing P12 from the device, installing it on windows, contacting the server and receiving a consistent response (200 HTTP-OK).

What have I changed . From the code samples I got (from here and here ), I had to change a few things. I use HttpsURLConnection and not OkHttpClient as @Than is used there (but it doesn’t matter), I can’t provide certificates like Rich Freedman did (he had a certificate and I get it through PKCS # 10 and # 7). therefore, I created a CustomTrustManager that will trust the server certificate, and for this reason I use SpongyCastle (v1.5.0.0, if it matters, it is set as the provider inserted in 0), and the certificate is not saved, but everything is done in memory .

The question is what to do next:

  • How can I find out what the server expects (client-certificate wise)?
  • , ( ) ?
  • ? (, Fiddler, SSL)

!

+1
1

, , .

, X509KeyManager, , KeyManagerFactory:

@DebugLog , . , . Log.d .

:

class MyKeyManager implements X509KeyManager {

    private final X509KeyManager keyManager;

    MyKeyManager(X509KeyManager keyManager) {
        this.keyManager = keyManager;
    }

    @DebugLog
    @Override
    public String chooseClientAlias(String[] strings, Principal[] principals, Socket socket) {
        return this.keyManager.chooseClientAlias(strings, principals, socket);
    }

    @DebugLog
    @Override
    public String chooseServerAlias(String s, Principal[] principals, Socket socket) {
        return keyManager.chooseServerAlias(s, principals, socket);
    }

    @DebugLog
    @Override
    public X509Certificate[] getCertificateChain(String s) {
        return keyManager.getCertificateChain(s);
    }

    @DebugLog
    @Override
    public String[] getClientAliases(String s, Principal[] principals) {
        return keyManager.getClientAliases(s, principals);
    }

    @DebugLog
    @Override
    public String[] getServerAliases(String s, Principal[] principals) {
        return keyManager.getServerAliases(s, principals);
    }

    @DebugLog
    @Override
    public PrivateKey getPrivateKey(String s) {
        return keyManager.getPrivateKey(s);
    }
}

init SSLContext

KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, password);

final X509KeyManager origKm = (X509KeyManager) kmf.getKeyManagers()[0];
X509KeyManager km = new MyKeyManager(origKm);

SSLContext sslCtx = SSLContext.getInstance("TLS");
sslCtx.init(new KeyManager[]{km}, tmf.getTrustManagers(), null);

, , ( serwer) keymanager.

+4

All Articles