This post is a follow up to CrazyBob’s great post on the same subject. A big thanks to him for posting it as it helped me and my team get to our final result of getting Android to communicate with a custom CA (Thawte in this case).
The Original Problem
In short, I was getting the dreaded error:
SSLException: Not trusted server certificate
This happened in Android when attempting to contact one of our servers in Germany. The problem is that the server is signed with a Thawte certificate and unfortunately Thawte is not in the list of known CA‘s in Android source code (yes, there is a list).
Crazy Bob’s post got us down the correct path, however we ran into an issue where the app would start throwing another error:
javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
Great. After some investigation we determined that Crazy Bob’s post was using a self signed certificate for their server. Therefore, when he generated his .pem file from this command:
echo | openssl s_client -connect ${MY_SERVER}:443 2>&1 | \ sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > mycert.pem
This code grabbed the public certificate of the server. Being that it was self signed, this is exactly what they wanted. However, if you did NOT self sign your cert, you’ll want to grab the root cert of your CA and then work with that instead. Therefore, if Thawte signed your cert, you’ll want Thawtes Root CA cert to do your signing in your keystore.
How to Find your Root Cert
Please note, your milage may vary, but here’s how we found it. We ran the following command:
openssl s_client -connect api.yourserver.de:443
In the output we saw the following:
CN=thawte Primary Root CA
We then were able to look up the Root CA certificate on Thawtes site via their Root Certificates page. We grabbed the first one as the other two Root CA’s (#4 and #5) were invalid and/or out of date. Here’s the link to the one we used.
Generating the Keystore
Using this CA, we generated the same keystore that Crazy Bob did, with this command:
export CLASSPATH=bcprov-jdk16-146.jar CERTSTORE=res/raw/mystore.bks if [ -a $CERTSTORE ]; then rm $CERTSTORE || exit 1 fi keytool \ -import \ -v \ -trustcacerts \ -alias 0 \ -file <(openssl x509 -in thawte_Primary_Root_CA.pem) \ -keystore $CERTSTORE \ -storetype BKS \ -provider org.bouncycastle.jce.provider.BouncyCastleProvider \ -providerpath /usr/share/java/bcprov.jar \ -storepass ez24getAfter this, I now had the “mystore.bks” file and followed Crazy Bob’s instructions again and used that to build my trust store as shown in step three of Crazy Bob’s post here.
Done
After all that work, I can now talk to my server without compromising security as I’m not accepting all ssl certs out of the box, but only the ones that I approve of. Please note, if you’re dealing with many different servers with different CA authorities then you may need to import many different pem files into the keystore.