No Peer Certificate' Error in Android 2.3 But Not in 4

No peer certificate' error in Android 2.3 but NOT in 4

This thread was really helpful when I debugged a similar issue.

Summary Android 2.3 HTTPS/SSL checklist:

  • If your CA is in Android's 2.3 list of trusted CA's -- and Thawte is -- there's no need to include the certificate in the app.
  • Android 2.3 does not support Server Name Indication so if your server is relying on it for SSL handshaking, Android may not be getting the certificates you're expecting.
  • Do you have certificate chain on the server installed, and is it ordered correctly? Most browsers handle out-of-order certificate chains but Android 2.3 does not. bdc's answer in the thread I mentioned above describes how to check the validity of your SSL certificate and chain with "openssl s_client -connect yourserver.com:443".
  • When digging up that old 2.3 device you have in your bottom drawer, please ensure its date and time are set correctly after being powerless for too long.

Android SSL - No Peer Certificate

Even though this question has an accepted answer I thought it worthwhile to answer since I got the same error on an older Android device running 2.3.3:

javax.net.ssl.SSLPeerUnverifiedException: No peer certificate

After reading several different related questions on SO I came to the conclusion that this can happen for two (maybe more?) reasons:

  • Improper installation of an intermediate certificate
  • Incorrect ordering of the certificate chain

In my case it was an incorrect ordering of certificates. As an example I'm posting the cert order from this question with the insightful answer from user bdc. You can get the certificate ordering by doing the following from a terminal:

openssl s_client -connect eu.battle.net:443

(obviously replacing eu.battle.net with your own server). In the case of eu.battle.net at that time the order was:

Certificate chain
0 s:/C=US/ST=California/L=Irvine/O=Blizzard Entertainment, Inc./CN=*.battle.net
i:/C=US/O=Thawte, Inc./CN=Thawte SSL CA
1 s:/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA
i:/C=ZA/ST=Western Cape/L=Cape Town/O=Thawte Consulting cc/OU=Certification Services Division/CN=Thawte Premium Server CA/emailAddress=premium-server@thawte.com
2 s:/C=US/O=Thawte, Inc./CN=Thawte SSL CA
i:/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA

While it should have been:

Certificate chain
0 s:/C=US/ST=California/L=Irvine/O=Blizzard Entertainment, Inc./CN=*.battle.net
i:/C=US/O=Thawte, Inc./CN=Thawte SSL CA
1 s:/C=US/O=Thawte, Inc./CN=Thawte SSL CA
i:/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA
2 s:/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA
i:/C=ZA/ST=Western Cape/L=Cape Town/O=Thawte Consulting cc/OU=Certification Services Division/CN=Thawte Premium Server CA/emailAddress=premium-server@thawte.com

The rule is that the issuer of cert "n" in the chain should match the subject of cert "n+1".

Once I found the problem it was trivial to change the cert order on the server and things immediately started working on the Android 2.3.3 device. I guess it's good that older Android versions are a bit pesky about cert order, but it was also a nightmare since newer Android versions reorder the certs automatically. Hell, even an old iPhone 3GS worked with certs out of order.

How do I avoid getting No peer certificate error when connecting to this HTTPS site on Android?

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 :)

Safely fixing: javax.net.ssl.SSLPeerUnverifiedException: No peer certificate

It turns out my code was fine and the problem was that the server was not returning the full certificate chain. For more information see this SO post and this superuser post:

SSL certificate is not trusted - on mobile only

https://superuser.com/questions/347588/how-do-ssl-chains-work

Https connection, differences between Android 2.3 and 4

Your certifying authority probably is not listed in the 2.3.3 version of Android, but is in the 4.x version. To find out for sure check the keystore on both devices.

Using ADB from the command line you can dump out android's keystore to a file and check to see if that issuer is available in your keystore (may need to be root).
adb pull /system/etc/security/cacerts.bks cacerts.bks

Download and install Portecle (from: http://portecle.sourceforge.net/)
Select File / Open Keystore... and choose the cacerts.bks file.
Select Tools / Keystore Report and copy that information into a text editor to look for the CN specified in the certificate found from the web browser. In my case I couldn't find one from "Cybertrust Public SureServer SV CA".

Browse to the website you are interested in using https://example.website.com/ on your computer web browser and find out who the CN is. Compare that to the keystore as shown above. If it is not in the keystore you will need to add it.

NOTE: Android 4.0 phones have a different method for storing certificates and don't use the cacerts.bks file mentioned below. For them you should be able to open the desired https site in the web browser and add the desired certificates that way.

I had connection issues to facebook and redbox. To fix my problem and update my android 2.3.3 phone certificates I copied the one from the android 3.2 emulator and put that on my phone:

  1. Create and start an android 3.2 virtual device.
  2. Copy the cacerts.bks file from the emulator (make sure your other device is not connected).
    adb pull /system/etc/security/cacerts.bks cacerts.bks
  3. Disconnect the emulator.
  4. Connect your device to be updated (must be root). You may need to remount the /system folder as rw for read/write capabilities. For mounting issues, see: this link
  5. Save a copy of the old cert file from your device:
    adb pull /system/etc/security/cacerts.bks cacerts.bks.old
  6. Put the updated cert file on your device
    adb push cacerts.bks /system/etc/security/
  7. Reboot the device
  8. Reconnect and verify the new cacert file was loaded.


Related Topics



Leave a reply



Submit