6

I am developing an Android application which needs to access QuickPay's service ("https://secure.quickpay.dk/form") through an Http-client. But I keep getting errors when accessing the page. More specifically I get a "No Peer Certificate" error message. I tried several different things already: I tried adding the root certificate to my keystore, and to use this keystore when connecting, following this procedure: adding certificate to keystore. I also tried accepting all certificates, following the proposed method from here: accepting certificate for android. I have successfully connected to other https sites, but can not seem to connect to this one. I have tried on different Android devices (1.6, 2.2, and 2.3.3). Can anyone succeed in connecting to quickpay's site, or can anyone come up with a possible solution/fix?

//Update: If I access this site with my WebView: payment window examples, and press one of the buttons (which basically just launches a http post with some pre-defined variables) I am able to connect to the site in the webview on Android 2.3.3. Furthermore, I found out that I get a reply from the site if I try to launch the above application on Android 3.1! Any suggestions?

public class MyHttpClient extends DefaultHttpClient {

final Context context;

public MyHttpClient(Context context) {
    this.context = context;
    loadHttps();
}

private void loadHttps() {
    String url = "https://secure.quickpay.dk/form";
    HttpPost httpPost = new HttpPost(url);
    try {
        System.out.println("Executing");
        this.execute(httpPost);
    } catch (UnsupportedEncodingException e) {
        System.out.println(e.getMessage());
    } catch (ClientProtocolException e) {
        System.out.println(e.getMessage());
    } catch (IOException e) {
        System.out.println(e);
    }
}

@Override
protected ClientConnectionManager createClientConnectionManager() {
    SchemeRegistry registry = new SchemeRegistry();
    registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
    registry.register(new Scheme("https", newSslSocketFactory(), 443));
    return new SingleClientConnManager(getParams(), registry);
}

private SSLSocketFactory newSslSocketFactory() {
    try {
        KeyStore trusted = KeyStore.getInstance("BKS");
        InputStream in = context.getResources().openRawResource(R.raw.test);
        try {
            trusted.load(in, "mysecret".toCharArray());
        } finally {
            in.close();
        }
        SSLSocketFactory sf = new SSLSocketFactory(trusted);
        return sf;
    } catch (Exception e) {
        throw new AssertionError(e);
    }
}

}


StackTrace:

WARN/System.err(8459)        at org.apache.harmony.xnet.provider.jsse.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java    258)
 WARN/System.err(8459)       at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java  93)
 WARN/System.err(8459)       at org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java    381)
 WARN/System.err(8459)       at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java   177)
 WARN/System.err(8459)       at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java 164)
 WARN/System.err(8459)       at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java 119)
 WARN/System.err(8459)       at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java  359)
 WARN/System.err(8459)       at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java  555)
 WARN/System.err(8459)       at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java  487)
 WARN/System.err(8459)       at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java  465)
 WARN/System.err(8459)       at test.https.MyHttpClient.loadHttps(MyHttpClient.java 34)
 WARN/System.err(8459)       at test.https.MyHttpClient.<init>(MyHttpClient.java    26)
 WARN/System.err(8459)       at test.https.HttpsTesterActivity.onCreate(HttpsTesterActivity.java    60)
 WARN/System.err(8459)       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java   1047)
 WARN/System.err(8459)       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java    1615)
 WARN/System.err(8459)       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java 1667)
 WARN/System.err(8459)       at android.app.ActivityThread.access$1500(ActivityThread.java  117)
 WARN/System.err(8459)       at android.app.ActivityThread$H.handleMessage(ActivityThread.java  935)
 WARN/System.err(8459)       at android.os.Handler.dispatchMessage(Handler.java 99)
 WARN/System.err(8459)       at android.os.Looper.loop(Looper.java  123)
 WARN/System.err(8459)       at android.app.ActivityThread.main(ActivityThread.java 3687)
 WARN/System.err(8459)       at java.lang.reflect.Method.invokeNative(Native Method)    
 WARN/System.err(8459)       at java.lang.reflect.Method.invoke(Method.java 507)
 WARN/System.err(8459)       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java  842)
 WARN/System.err(8459)       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java 600)
Community
  • 1
  • 1
erik_beus
  • 161
  • 1
  • 1
  • 7
  • Is the certificate that you are getting a generic site certificate, or is this a personal (or company) certificate that you got from QuickPay? What format is it? pkx? p12? – Peter Knego Sep 28 '11 at 13:33
  • 1
    Please post the entire message and stack trace. – user207421 Sep 28 '11 at 23:53
  • @PeterKnego, I downloaded the root certificate from QuickPay's site through my browser. The certificate has been given by Equifax. I then converted the certificate to a p12 certificate in order to load it into Android. – erik_beus Sep 29 '11 at 18:30
  • @EJP The code for loading in the keystore, and trying to connect to the site has been added to the original question above... The error i get is this: javax.net.ssl.SSLPeerUnverifiedException: No peer certificate – erik_beus Sep 29 '11 at 18:32
  • 1
    Please post the entire message *and stack trace.* exc.printStackTrace(). And are you getting that at the client? or at the server? – user207421 Sep 30 '11 at 00:46
  • @EJP, posted the stack trace above. As I have no control of the server, the errors described are experienced at the client side. – erik_beus Sep 30 '11 at 20:17
  • you could give this a try: http://www.virtualzone.de/2011-02-27/how-to-use-apache-httpclient-with-httpsssl-on-android/ – Someone Somewhere Mar 14 '12 at 21:42
  • I asked for the entire message and stack trace, i.e. the output of `printStackTrace()`, and you haven't provided it. – user207421 Jan 09 '17 at 07:27

3 Answers3

2

Just to sum up, I fixed this issue by sticking to the WebView approach. The interaction with the API was moved to a server, creating an intermediate communication point which handles the certificate issues. Not the most elegant solution but it works :)

erik_beus
  • 161
  • 1
  • 1
  • 7
0

Try using UrlConnection class to make connections, and see whether you can avoid this "no peer certificate" error.

Abhinav Saxena
  • 1,990
  • 2
  • 24
  • 55
0

This is very mysterious. The only way an HTTPS/SSL server can avoid sending a certificate is if both sides agree to operate the SSL connection in reverse, where the server is the SSL client and the client is the SSL server, so the certificate travels in the other direction. But I can't see anything in your code that enables that mode, and it would have to be enabled at the other end too. And you would have to be providing a certificate yourself from your keystore ... Very strange.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • I do provide a certificate, here called "test", which I load in from my "raw" resources (see code above). This is the converted root certificate I obtained and saved with my browser. – erik_beus Oct 02 '11 at 13:49